summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2012-11-07 20:41:56 +0000
committerMike Frysinger <vapier@gentoo.org>2012-11-07 20:41:56 +0000
commit35054f32dfe1abe2e6f5b33bde73758b32677a21 (patch)
tree4d94c31296241ce61bf6ce8b6b0b8747718b3858 /net-misc/mediatomb/files
parentSlot gstreamer dependencies in preparation for gstreamer-1.0. (diff)
downloadgentoo-2-35054f32dfe1abe2e6f5b33bde73758b32677a21.tar.gz
gentoo-2-35054f32dfe1abe2e6f5b33bde73758b32677a21.tar.bz2
gentoo-2-35054f32dfe1abe2e6f5b33bde73758b32677a21.zip
Fix inotify and hard links. Add support for caching thumbnails.
(Portage version: 2.2.0_alpha142/cvs/Linux x86_64, signed Manifest commit with key FB7C4156)
Diffstat (limited to 'net-misc/mediatomb/files')
-rw-r--r--net-misc/mediatomb/files/mediatomb-0.12.1-inotify-hard-links.patch34
-rw-r--r--net-misc/mediatomb/files/mediatomb-0.12.1-thumb-cache.patch233
2 files changed, 267 insertions, 0 deletions
diff --git a/net-misc/mediatomb/files/mediatomb-0.12.1-inotify-hard-links.patch b/net-misc/mediatomb/files/mediatomb-0.12.1-inotify-hard-links.patch
new file mode 100644
index 000000000000..af9a887befe0
--- /dev/null
+++ b/net-misc/mediatomb/files/mediatomb-0.12.1-inotify-hard-links.patch
@@ -0,0 +1,34 @@
+make sure new hard links get processed like new files by handling
+the IN_CREATE flag properly
+
+patch by Mike Frysinger
+
+--- a/src/autoscan_inotify.cc
++++ b/src/autoscan_inotify.cc
+@@ -281,7 +284,7 @@
+ }
+ }
+
+- if (adir != nil && mask & (IN_DELETE | IN_DELETE_SELF | IN_MOVE_SELF | IN_CLOSE_WRITE | IN_MOVED_FROM | IN_MOVED_TO | IN_UNMOUNT))
++ if (adir != nil && mask & (IN_DELETE | IN_DELETE_SELF | IN_MOVE_SELF | IN_CLOSE_WRITE | IN_MOVED_FROM | IN_MOVED_TO | IN_UNMOUNT | IN_CREATE))
+ {
+ String fullPath;
+ if (mask & IN_ISDIR)
+@@ -289,7 +292,7 @@
+ else
+ fullPath = path;
+
+- if (! (mask & IN_MOVED_TO))
++ if (! (mask & (IN_MOVED_TO | IN_CREATE)))
+ {
+ log_debug("deleting %s\n", fullPath.c_str());
+
+@@ -312,7 +315,7 @@
+ if (objectID != INVALID_OBJECT_ID)
+ cm->removeObject(objectID);
+ }
+- if (mask & (IN_CLOSE_WRITE | IN_MOVED_TO))
++ if (mask & (IN_CLOSE_WRITE | IN_MOVED_TO | IN_CREATE))
+ {
+ log_debug("adding %s\n", path.c_str());
+ // path, recursive, async, hidden, low priority, cancellable
diff --git a/net-misc/mediatomb/files/mediatomb-0.12.1-thumb-cache.patch b/net-misc/mediatomb/files/mediatomb-0.12.1-thumb-cache.patch
new file mode 100644
index 000000000000..5b26de0f271a
--- /dev/null
+++ b/net-misc/mediatomb/files/mediatomb-0.12.1-thumb-cache.patch
@@ -0,0 +1,233 @@
+http://sourceforge.net/tracker/?func=detail&aid=3291468&group_id=129766&atid=715782
+
+[PATCH] Add the cache feature of ffmpegthumbnailer.
+
+I want the cache feature of ffmpegthumbnailer because my machine
+is not powerful :-(
+So I created this patch for the cache feature.
+
+This patch adds a new option "cache-dir" in config.xml.
+If not specifying any string, the cache feature is disable.
+And specifying some directory, the cache feature is enable
+and the cache files will be created under the directory.
+
+Signed-off-by: Ken'ichi Ohmichi <ken1ohmichi@gmail.com>
+---
+diff --git a/src/common.h b/src/common.h
+index d1998b3..358f4d1 100644
+--- a/src/common.h
++++ b/src/common.h
+@@ -367,6 +367,8 @@
+ #define DEFAULT_FFMPEGTHUMBNAILER_FILMSTRIP_OVERLAY YES
+ #define DEFAULT_FFMPEGTHUMBNAILER_WORKAROUND_BUGS NO
+ #define DEFAULT_FFMPEGTHUMBNAILER_IMAGE_QUALITY 8
++ #define DEFAULT_FFMPEGTHUMBNAILER_CACHE_DIR_ENABLED YES
++ #define DEFAULT_FFMPEGTHUMBNAILER_CACHE_DIR ""
+ #endif
+
+ #if defined(HAVE_LASTFMLIB)
+diff --git a/src/config_manager.cc b/src/config_manager.cc
+index 8c975f8..2902090 100644
+--- a/src/config_manager.cc
++++ b/src/config_manager.cc
+@@ -1873,6 +1873,24 @@ void ConfigManager::validate(String serverhome)
+
+ NEW_INT_OPTION(temp_int);
+ SET_INT_OPTION(CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_IMAGE_QUALITY);
++
++ temp = getOption("/server/extended-runtime-options/ffmpegthumbnailer/"
++ "cache-dir", DEFAULT_FFMPEGTHUMBNAILER_CACHE_DIR);
++
++ NEW_OPTION(temp);
++ SET_OPTION(CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_CACHE_DIR);
++
++ temp = getOption("/server/extended-runtime-options/ffmpegthumbnailer/"
++ "cache-dir/attribute::enabled",
++ DEFAULT_FFMPEGTHUMBNAILER_CACHE_DIR_ENABLED);
++
++ if (!validateYesNo(temp))
++ throw _Exception(_("Error in config file: "
++ "invalid \"enabled\" attribute value in "
++ "ffmpegthumbnailer <cache-dir> tag"));
++
++ NEW_BOOL_OPTION(temp == YES ? true : false);
++ SET_BOOL_OPTION(CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_CACHE_DIR_ENABLED);
+ }
+ #endif
+
+diff --git a/src/config_manager.h b/src/config_manager.h
+index 52b9842..a447a60 100644
+--- a/src/config_manager.h
++++ b/src/config_manager.h
+@@ -110,6 +110,8 @@ typedef enum
+ CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_FILMSTRIP_OVERLAY,
+ CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_WORKAROUND_BUGS,
+ CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_IMAGE_QUALITY,
++ CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_CACHE_DIR_ENABLED,
++ CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_CACHE_DIR,
+ #endif
+ CFG_SERVER_EXTOPTS_MARK_PLAYED_ITEMS_ENABLED,
+ CFG_SERVER_EXTOPTS_MARK_PLAYED_ITEMS_STRING_MODE_PREPEND,
+diff --git a/src/metadata/ffmpeg_handler.cc b/src/metadata/ffmpeg_handler.cc
+index a637d9c..8e7ef23 100644
+--- a/src/metadata/ffmpeg_handler.cc
++++ b/src/metadata/ffmpeg_handler.cc
+@@ -50,6 +50,9 @@
+ // INT64_C is not defined in ffmpeg/avformat.h but is needed
+ // macro defines included via autoconfig.h
+ #include <stdint.h>
++#include <sys/stat.h>
++#include <errno.h>
++#include <string.h>
+
+ //#ifdef FFMPEG_NEEDS_EXTERN_C
+ extern "C"
+@@ -279,6 +282,118 @@ void FfmpegHandler::fillMetadata(Ref<CdsItem> item)
+ av_close_input_file(pFormatCtx);
+ }
+
++static bool _mkdir(const char *path)
++{
++ int ret = mkdir(path, 0777);
++
++ if (ret == 0) {
++ // Make sure we are +x in case of restrictive umask that strips +x.
++ struct stat st;
++ if (stat(path, &st)) {
++ log_warning("could not stat(%s): %s\n", path, strerror(errno));
++ return -1;
++ }
++ mode_t xbits = S_IXUSR | S_IXGRP | S_IXOTH;
++ if (!(st.st_mode & xbits)) {
++ if (chmod(path, st.st_mode | xbits)) {
++ log_warning("could not chmod(%s, +x): %s\n", path, strerror(errno));
++ return -1;
++ }
++ }
++ }
++
++ return ret;
++}
++
++static bool makeThumbnailCacheDir(String& path)
++{
++ char *path_temp = strdup(path.c_str());
++ char *last_slash = strrchr(path_temp, '/');
++ char *slash = last_slash;
++ bool ret = false;
++
++ if (!last_slash)
++ return ret;
++
++ // Assume most dirs exist, so scan backwards first.
++ // Avoid stat/access checks due to TOCTOU races.
++ errno = 0;
++ for (slash = last_slash; slash > path_temp; --slash) {
++ if (*slash != '/')
++ continue;
++ *slash = '\0';
++ if (_mkdir(path_temp) == 0) {
++ // Now we can forward scan.
++ while (slash < last_slash) {
++ *slash = DIR_SEPARATOR;
++ if (_mkdir(path_temp) < 0)
++ // Allow EEXIST in case of someone else doing `mkdir`.
++ if (errno != EEXIST)
++ goto done;
++ slash += strlen(slash);
++ }
++ if (slash == last_slash)
++ ret = true;
++ break;
++ } else if (errno == EEXIST) {
++ ret = true;
++ break;
++ } else if (errno != ENOENT) {
++ break;
++ }
++ }
++
++ done:
++ free(path_temp);
++ return ret;
++}
++
++static String getThumbnailCacheFilePath(String& movie_filename, bool create)
++{
++ Ref<ConfigManager> cfg = ConfigManager::getInstance();
++ String cache_dir = cfg->getOption(CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_CACHE_DIR);
++
++ if (cache_dir.length() == 0) {
++ String home_dir = cfg->getOption(CFG_SERVER_HOME);
++ cache_dir = home_dir + "/cache-dir";
++ }
++
++ cache_dir = cache_dir + movie_filename + "-thumb.jpg";
++ if (create && !makeThumbnailCacheDir(cache_dir))
++ cache_dir = "";
++ return cache_dir;
++}
++
++static bool readThumbnailCacheFile(String movie_filename, uint8_t **ptr_img, size_t *size_img)
++{
++ String path = getThumbnailCacheFilePath(movie_filename, false);
++ FILE *fp = fopen(path.c_str(), "rb");
++ if (!fp)
++ return false;
++
++ size_t bytesRead;
++ uint8_t buffer[1024];
++ *ptr_img = NULL;
++ *size_img = 0;
++ while ((bytesRead = fread(buffer, 1, sizeof(buffer), fp)) > 0) {
++ *ptr_img = (uint8_t *)realloc(*ptr_img, *size_img + bytesRead);
++ memcpy(*ptr_img + *size_img, buffer, bytesRead);
++ *size_img += bytesRead;
++ }
++ fclose(fp);
++ return true;
++}
++
++static void writeThumbnailCacheFile(String movie_filename, uint8_t *ptr_img, int size_img)
++{
++ String path = getThumbnailCacheFilePath(movie_filename, true);
++ FILE *fp = fopen(path.c_str(), "wb");
++ if (!fp)
++ return;
++ fwrite(ptr_img, sizeof(uint8_t), size_img, fp);
++ fclose(fp);
++}
++
+ Ref<IOHandler> FfmpegHandler::serveContent(Ref<CdsItem> item, int resNum, off_t *data_size)
+ {
+ *data_size = -1;
+@@ -288,6 +403,18 @@ Ref<IOHandler> FfmpegHandler::serveContent(Ref<CdsItem> item, int resNum, off_t
+ if (!cfg->getBoolOption(CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_ENABLED))
+ return nil;
+
++ if (cfg->getBoolOption(CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_CACHE_DIR_ENABLED)) {
++ uint8_t *ptr_image;
++ size_t size_image;
++ if (readThumbnailCacheFile(item->getLocation(),
++ &ptr_image, &size_image)) {
++ *data_size = (off_t)size_image;
++ Ref<IOHandler> h(new MemIOHandler(ptr_image, size_image));
++ free(ptr_image);
++ log_debug("Returning cached thumbnail for file: %s\n", item->getLocation().c_str());
++ return h;
++ }
++ }
+ #ifdef FFMPEGTHUMBNAILER_OLD_API
+ video_thumbnailer *th = create_thumbnailer();
+ image_data *img = create_image_data();
+@@ -318,6 +445,10 @@ Ref<IOHandler> FfmpegHandler::serveContent(Ref<CdsItem> item, int resNum, off_t
+ #endif // old api
+ throw _Exception(_("Could not generate thumbnail for ") +
+ item->getLocation());
++ if (cfg->getBoolOption(CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_CACHE_DIR_ENABLED)) {
++ writeThumbnailCacheFile(item->getLocation(),
++ img->image_data_ptr, img->image_data_size);
++ }
+
+ *data_size = (off_t)img->image_data_size;
+ Ref<IOHandler> h(new MemIOHandler((void *)img->image_data_ptr,