diff options
| -rw-r--r-- | src/plugins/Input/cue/cuemetadatamodel.cpp | 9 | ||||
| -rw-r--r-- | src/plugins/Input/cue/cuemetadatamodel.h | 3 | ||||
| -rw-r--r-- | src/plugins/Input/flac/flacmetadatamodel.cpp | 8 | ||||
| -rw-r--r-- | src/plugins/Input/wavpack/wavpackmetadatamodel.cpp | 8 | ||||
| -rw-r--r-- | src/plugins/Input/wavpack/wavpackmetadatamodel.h | 1 | ||||
| -rw-r--r-- | src/qmmp/metadatamanager.cpp | 108 | ||||
| -rw-r--r-- | src/qmmp/metadatamanager.h | 32 |
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; |
