aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortrialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38>2016-10-06 20:21:07 +0000
committertrialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38>2016-10-06 20:21:07 +0000
commit933204b47d8933c6cbd20a6faf46be9df8305f4e (patch)
treea90c71d47d02553e238580e31674824019c4b1d6
parentcc22f5ceedf9f3d22e52b2dd387f0237e390a9cf (diff)
downloadqmmp-933204b47d8933c6cbd20a6faf46be9df8305f4e.tar.gz
qmmp-933204b47d8933c6cbd20a6faf46be9df8305f4e.tar.bz2
qmmp-933204b47d8933c6cbd20a6faf46be9df8305f4e.zip
improved cover cache
git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@6773 90c681e8-e032-0410-971d-27865f9a5e38
-rw-r--r--src/plugins/Input/cue/cuemetadatamodel.cpp9
-rw-r--r--src/plugins/Input/cue/cuemetadatamodel.h3
-rw-r--r--src/plugins/Input/flac/flacmetadatamodel.cpp8
-rw-r--r--src/plugins/Input/wavpack/wavpackmetadatamodel.cpp8
-rw-r--r--src/plugins/Input/wavpack/wavpackmetadatamodel.h1
-rw-r--r--src/qmmp/metadatamanager.cpp108
-rw-r--r--src/qmmp/metadatamanager.h32
7 files changed, 92 insertions, 77 deletions
diff --git a/src/plugins/Input/cue/cuemetadatamodel.cpp b/src/plugins/Input/cue/cuemetadatamodel.cpp
index 612443367..c53a42de5 100644
--- a/src/plugins/Input/cue/cuemetadatamodel.cpp
+++ b/src/plugins/Input/cue/cuemetadatamodel.cpp
@@ -1,5 +1,5 @@
/***************************************************************************
- * Copyright (C) 2009 by Ilya Kotov *
+ * Copyright (C) 2009-2016 by Ilya Kotov *
* forkotov02@hotmail.ru *
* *
* This program is free software; you can redistribute it and/or modify *
@@ -51,12 +51,7 @@ QHash<QString, QString> CUEMetaDataModel::audioProperties()
return ap;
}
-QPixmap CUEMetaDataModel::cover()
-{
- return MetaDataManager::instance()->getCover(m_path);
-}
-
QString CUEMetaDataModel::coverPath()
{
- return MetaDataManager::instance()->getCoverPath(m_path);
+ return MetaDataManager::instance()->findCoverFile(m_path);
}
diff --git a/src/plugins/Input/cue/cuemetadatamodel.h b/src/plugins/Input/cue/cuemetadatamodel.h
index e92693e30..065430f78 100644
--- a/src/plugins/Input/cue/cuemetadatamodel.h
+++ b/src/plugins/Input/cue/cuemetadatamodel.h
@@ -1,5 +1,5 @@
/***************************************************************************
- * Copyright (C) 2009 by Ilya Kotov *
+ * Copyright (C) 2009-2016 by Ilya Kotov *
* forkotov02@hotmail.ru *
* *
* This program is free software; you can redistribute it and/or modify *
@@ -32,7 +32,6 @@ public:
CUEMetaDataModel(const QString &url, QObject *parent);
~CUEMetaDataModel();
QHash<QString, QString> audioProperties();
- QPixmap cover();
QString coverPath();
private:
diff --git a/src/plugins/Input/flac/flacmetadatamodel.cpp b/src/plugins/Input/flac/flacmetadatamodel.cpp
index b5d0cd1bb..7f8965de5 100644
--- a/src/plugins/Input/flac/flacmetadatamodel.cpp
+++ b/src/plugins/Input/flac/flacmetadatamodel.cpp
@@ -106,6 +106,7 @@ QList<TagModel* > FLACMetaDataModel::tags()
QPixmap FLACMetaDataModel::cover()
{
//embedded cover
+ QPixmap cover;
FLAC__StreamMetadata *metadata;
FLAC__metadata_get_picture (qPrintable(m_path),
&metadata,
@@ -114,18 +115,15 @@ QPixmap FLACMetaDataModel::cover()
if(metadata)
{
FLAC__StreamMetadata_Picture *pict = &metadata->data.picture;
- QPixmap cover;
cover.loadFromData(QByteArray((char *)pict->data, (int) pict->data_length));
FLAC__metadata_object_delete(metadata);
- return cover;
}
- QString cPath = coverPath();
- return cPath.isEmpty() ? QPixmap() : QPixmap(cPath);
+ return cover;
}
QString FLACMetaDataModel::coverPath()
{
- return MetaDataManager::instance()->getCoverPath(m_path);
+ return MetaDataManager::instance()->findCoverFile(m_path);
}
VorbisCommentModel::VorbisCommentModel(TagLib::Ogg::XiphComment *tag, TagLib::File *file) : TagModel(TagModel::Save)
diff --git a/src/plugins/Input/wavpack/wavpackmetadatamodel.cpp b/src/plugins/Input/wavpack/wavpackmetadatamodel.cpp
index e2d978453..61838a3f3 100644
--- a/src/plugins/Input/wavpack/wavpackmetadatamodel.cpp
+++ b/src/plugins/Input/wavpack/wavpackmetadatamodel.cpp
@@ -83,15 +83,9 @@ QList<TagModel* > WavPackMetaDataModel::tags()
return m_tags;
}
-QPixmap WavPackMetaDataModel::cover()
-{
- QString cPath = coverPath();
- return cPath.isEmpty() ? QPixmap() : QPixmap(cPath);
-}
-
QString WavPackMetaDataModel::coverPath()
{
- return MetaDataManager::instance()->getCoverPath(m_path);
+ return MetaDataManager::instance()->findCoverFile(m_path);
}
WavPackFileTagModel::WavPackFileTagModel(WavpackContext *ctx) : TagModel(TagModel::Save)
diff --git a/src/plugins/Input/wavpack/wavpackmetadatamodel.h b/src/plugins/Input/wavpack/wavpackmetadatamodel.h
index a9fd30dd8..823e3640e 100644
--- a/src/plugins/Input/wavpack/wavpackmetadatamodel.h
+++ b/src/plugins/Input/wavpack/wavpackmetadatamodel.h
@@ -34,7 +34,6 @@ public:
~WavPackMetaDataModel();
QHash<QString, QString> audioProperties();
QList<TagModel* > tags();
- QPixmap cover();
QString coverPath();
private:
diff --git a/src/qmmp/metadatamanager.cpp b/src/qmmp/metadatamanager.cpp
index c3388b510..17b241ce7 100644
--- a/src/qmmp/metadatamanager.cpp
+++ b/src/qmmp/metadatamanager.cpp
@@ -29,6 +29,8 @@
#include "qmmpsettings.h"
#include "metadatamanager.h"
+#define COVER_CACHE_SIZE 10
+
MetaDataManager* MetaDataManager::m_instance = 0;
MetaDataManager::MetaDataManager() : m_mutex(QMutex::Recursive)
@@ -41,6 +43,7 @@ MetaDataManager::MetaDataManager() : m_mutex(QMutex::Recursive)
MetaDataManager::~MetaDataManager()
{
+ clearCoverCache();
m_instance = 0;
}
@@ -177,65 +180,50 @@ bool MetaDataManager::supports(const QString &fileName) const
return false;
}
-QPixmap MetaDataManager::getCover(const QString &url)
+QPixmap MetaDataManager::getCover(const QString &url) const
{
- MetaDataModel *model = createMetaDataModel(url);
- if(model)
+ for(int i = 0; i < m_cover_cache.size(); ++i)
{
- QPixmap pix = model->cover();
- delete model;
- if(!pix.isNull())
- return pix;
+ if(m_cover_cache[i]->url == url)
+ return m_cover_cache[i]->coverPixmap;
}
- if(!url.contains("://") && m_settings->useCoverFiles())
+ m_cover_cache << createCoverCacheItem(url);
+
+ while(m_cover_cache.size() > COVER_CACHE_SIZE)
+ delete m_cover_cache.takeFirst();
+
+ return m_cover_cache.last()->coverPixmap;
+}
+
+QString MetaDataManager::getCoverPath(const QString &url) const
+{
+ for(int i = 0; i < m_cover_cache.size(); ++i)
{
- QString p = getCoverPath(url);
- if(!p.isEmpty())
- {
- if(m_cached_path == p)
- return m_cached_cover;
- QPixmap pix(p);
- if(pix.width() > 1024 || pix.height() > 1024)
- pix = pix.scaled(1024, 1024, Qt::KeepAspectRatio, Qt::SmoothTransformation);
- m_cached_path = p;
- m_cached_cover = pix;
- return pix;
- }
+ if(m_cover_cache[i]->url == url)
+ return m_cover_cache[i]->coverPath;
}
- return QPixmap();
+ m_cover_cache << createCoverCacheItem(url);
+
+ while(m_cover_cache.size() > COVER_CACHE_SIZE)
+ delete m_cover_cache.takeFirst();
+
+ return m_cover_cache.last()->coverPath;
}
-QString MetaDataManager::getCoverPath(const QString &url)
+QString MetaDataManager::findCoverFile(const QString &fileName) const
{
if(!m_settings->useCoverFiles())
return QString();
- if(url.contains("://")) //url
+
+ if(!QFile::exists(fileName))
{
- MetaDataModel *model = createMetaDataModel(url);
- if(model)
- {
- QString coverPath = model->coverPath();
- model->deleteLater();
- return coverPath;
- }
+ return QString();
}
- else //local file
- {
- QString key = QFileInfo(url).absolutePath();
- QString cover_path = m_cover_path_cache.value(key);
-
- if(!cover_path.isEmpty() && QFile::exists(cover_path))
- return cover_path;
- m_cover_path_cache.remove(key); //remove invalid key
- QFileInfoList l = findCoverFiles(key, m_settings->coverSearchDepth());
- cover_path = l.isEmpty() ? QString() : l.at(0).filePath();
- m_cover_path_cache.insert (key, cover_path);
- return cover_path;
- }
- return QString();
+ QFileInfoList l = findCoverFiles(QFileInfo(fileName).absoluteDir(), m_settings->coverSearchDepth());
+ return l.isEmpty() ? QString() : l.at(0).filePath();
}
QFileInfoList MetaDataManager::findCoverFiles(QDir dir, int depth) const
@@ -267,11 +255,37 @@ QFileInfoList MetaDataManager::findCoverFiles(QDir dir, int depth) const
return file_list;
}
+MetaDataManager::CoverCacheItem *MetaDataManager::createCoverCacheItem(const QString &url) const
+{
+ CoverCacheItem *item = new CoverCacheItem;
+ item->url = url;
+ MetaDataModel *model = createMetaDataModel(url);
+ if(model)
+ {
+ item->coverPath = model->coverPath();
+ item->coverPixmap = model->cover();
+ delete model;
+ }
+
+ if(!m_settings->useCoverFiles())
+ return item;
+
+ if(!url.contains("://") && item->coverPath.isEmpty())
+ item->coverPath = findCoverFile(url);
+
+ if(!item->coverPath.isEmpty() && item->coverPixmap.isNull())
+ item->coverPixmap = QPixmap(item->coverPath);
+
+ if(item->coverPixmap.width() > 1024 || item->coverPixmap.height() > 1024)
+ item->coverPixmap = item->coverPixmap.scaled(1024, 1024, Qt::KeepAspectRatio, Qt::SmoothTransformation);
+
+ return item;
+}
+
void MetaDataManager::clearCoverCache()
{
- m_cover_path_cache.clear();
- m_cached_cover = QPixmap();
- m_cached_path.clear();
+ qDeleteAll(m_cover_cache);
+ m_cover_cache.clear();
}
void MetaDataManager::prepareForAnotherThread()
diff --git a/src/qmmp/metadatamanager.h b/src/qmmp/metadatamanager.h
index ddd17af72..3c41dee40 100644
--- a/src/qmmp/metadatamanager.h
+++ b/src/qmmp/metadatamanager.h
@@ -82,16 +82,26 @@ public:
*/
bool supports(const QString &file) const;
/*!
- * Returns cover pixmap for the given file \b fileName,
+ * Returns the cover pixmap for the given file \b url,
* or returns an empty pixmap if cover is not available.
+ * IMPORTANT: to avoid infinite recursion, do not use this function inside \b MetaDataModel reimplementation.
*/
- QPixmap getCover(const QString &fileName);
+ QPixmap getCover(const QString &url) const;
/*!
- * Returns cover file path for the given file \b fileName, or returns
- * an empty string if cover file is not available. This function does not work
+ * Returns the cover file path for the given file \b url, or returns
+ * an empty string if the cover file is not available. This function does not work
* with embedded covers.
+ * IMPORTANT: to avoid infinite recursion, do not use this function inside \b MetaDataModel reimplementation.
*/
- QString getCoverPath(const QString &fileName);
+ QString getCoverPath(const QString &url) const;
+ /*!
+ * Returns the cover file path for the given local audio file, or returns
+ * an empty string if the cover file is not available.
+ * Unlike \b getCover and \b getCoverPath this function provides simple file search (without cache) and
+ * should be used inside \b MetaDataModel reimplementation.
+ * @param fileName Path of the local audio file.
+ */
+ QString findCoverFile(const QString &fileName) const;
/*!
* Clears cover path cache.
*/
@@ -110,10 +120,16 @@ public:
static void destroy();
private:
+ struct CoverCacheItem
+ {
+ QString url;
+ QString coverPath;
+ QPixmap coverPixmap;
+ };
+
QFileInfoList findCoverFiles(QDir dir, int depth) const;
- QMap <QString, QString> m_cover_path_cache;
- QPixmap m_cached_cover;
- QString m_cached_path;
+ CoverCacheItem *createCoverCacheItem(const QString &url) const;
+ mutable QList <CoverCacheItem *> m_cover_cache;
QmmpSettings *m_settings;
mutable QMutex m_mutex;