1
0
mirror of https://github.com/clementine-player/Clementine synced 2024-12-17 03:45:56 +01:00

Oops, actually load moodbar data on a different thread

This commit is contained in:
David Sansome 2012-05-27 20:05:01 +01:00
parent d939b4cf29
commit d36dd4d753
4 changed files with 33 additions and 29 deletions

View File

@ -20,6 +20,7 @@
#include "core/closure.h"
#include "core/utilities.h"
#include <QCoreApplication>
#include <QDir>
#include <QFileInfo>
#include <QNetworkDiskCache>
@ -32,6 +33,7 @@
MoodbarLoader::MoodbarLoader(QObject* parent)
: QObject(parent),
cache_(new QNetworkDiskCache(this)),
thread_(new QThread(this)),
kMaxActiveRequests(QThread::idealThreadCount() / 2 + 1),
save_alongside_originals_(false)
{
@ -62,12 +64,9 @@ MoodbarLoader::Result MoodbarLoader::Load(
}
// Are we in the middle of loading this moodbar already?
{
QMutexLocker l(&mutex_);
if (requests_.contains(url)) {
*async_pipeline = requests_[url];
return WillLoadAsync;
}
if (requests_.contains(url)) {
*async_pipeline = requests_[url];
return WillLoadAsync;
}
// Check if a mood file exists for this file already
@ -89,27 +88,29 @@ MoodbarLoader::Result MoodbarLoader::Load(
*data = cache_device->readAll();
return Loaded;
}
if (!thread_->isRunning())
thread_->start();
// There was no existing file, analyze the audio file and create one.
MoodbarPipeline* pipeline = new MoodbarPipeline(filename);
pipeline->moveToThread(thread_);
NewClosure(pipeline, SIGNAL(Finished(bool)),
this, SLOT(RequestFinished(MoodbarPipeline*,QUrl)),
pipeline, url);
{
QMutexLocker l(&mutex_);
requests_[url] = pipeline;
queued_requests_ << url;
}
requests_[url] = pipeline;
queued_requests_ << url;
QMetaObject::invokeMethod(this, "MaybeTakeNextRequest", Qt::QueuedConnection);
MaybeTakeNextRequest();
*async_pipeline = pipeline;
return WillLoadAsync;
}
void MoodbarLoader::MaybeTakeNextRequest() {
QMutexLocker l(&mutex_);
Q_ASSERT(QThread::currentThread() == qApp->thread());
if (active_requests_.count() > kMaxActiveRequests ||
queued_requests_.isEmpty()) {
return;
@ -119,10 +120,12 @@ void MoodbarLoader::MaybeTakeNextRequest() {
active_requests_ << url;
qLog(Info) << "Creating moodbar data for" << url.toLocalFile();
requests_[url]->Start();
QMetaObject::invokeMethod(requests_[url], "Start", Qt::QueuedConnection);
}
void MoodbarLoader::RequestFinished(MoodbarPipeline* request, const QUrl& url) {
Q_ASSERT(QThread::currentThread() == qApp->thread());
if (request->success()) {
qLog(Info) << "Moodbar data generated successfully for" << url.toLocalFile();
@ -149,12 +152,10 @@ void MoodbarLoader::RequestFinished(MoodbarPipeline* request, const QUrl& url) {
qLog(Debug) << "Deleting" << request;
// Remove the request from the active list and delete it
{
QMutexLocker l(&mutex_);
requests_.remove(url);
active_requests_.remove(url);
}
requests_.remove(url);
active_requests_.remove(url);
QTimer::singleShot(10, request, SLOT(deleteLater()));
QMetaObject::invokeMethod(this, "MaybeTakeNextRequest", Qt::QueuedConnection);
MaybeTakeNextRequest();
}

View File

@ -19,7 +19,6 @@
#define MOODBARLOADER_H
#include <QMap>
#include <QMutex>
#include <QObject>
#include <QSet>
@ -59,10 +58,10 @@ private:
private:
QNetworkDiskCache* cache_;
QThread* thread_;
const int kMaxActiveRequests;
QMutex mutex_;
QMap<QUrl, MoodbarPipeline*> requests_;
QList<QUrl> queued_requests_;
QSet<QUrl> active_requests_;

View File

@ -18,6 +18,9 @@
#include "moodbarpipeline.h"
#include "core/logging.h"
#include <QCoreApplication>
#include <QThread>
bool MoodbarPipeline::sIsAvailable = false;
QMutex MoodbarPipeline::sFftwMutex;
@ -67,9 +70,11 @@ GstElement* MoodbarPipeline::CreateElement(const QString& factory_name) {
return ret;
}
bool MoodbarPipeline::Start() {
void MoodbarPipeline::Start() {
Q_ASSERT(QThread::currentThread() != qApp->thread());
if (pipeline_) {
return false;
return;
}
pipeline_ = gst_pipeline_new("moodbar-pipeline");
@ -84,7 +89,7 @@ bool MoodbarPipeline::Start() {
if (!filesrc || !convert_element_ || !fftwspectrum || !moodbar || !appsink) {
pipeline_ = NULL;
emit Finished(false);
return false;
return;
}
QMutexLocker l(&sFftwMutex);
@ -115,8 +120,6 @@ bool MoodbarPipeline::Start() {
// Start playing
gst_element_set_state(pipeline_, GST_STATE_PLAYING);
return true;
}
void MoodbarPipeline::ReportError(GstMessage* msg) {

View File

@ -35,11 +35,12 @@ public:
static bool IsAvailable();
bool Start();
bool success() const { return success_; }
const QByteArray& data() const { return data_; }
public slots:
void Start();
signals:
void Finished(bool success);