Load xine in a background thread

This commit is contained in:
David Sansome 2010-02-03 21:48:00 +00:00
parent 8da8b04813
commit 90f7e2f9d2
7 changed files with 87 additions and 10 deletions

View File

@ -73,6 +73,8 @@ namespace Engine
*/
void infoMessage( const QString& );
void error( const QString& );
/** Transmits metadata package. */
void metaData( const Engine::SimpleMetaBundle& );

View File

@ -118,6 +118,7 @@ MainWindow::MainWindow(QWidget *parent)
// Player connections
connect(ui_.volume, SIGNAL(valueChanged(int)), player_, SLOT(SetVolume(int)));
connect(player_, SIGNAL(InitFinished()), SLOT(PlayerInitFinished()));
connect(player_, SIGNAL(Error(QString)), SLOT(ReportError(QString)));
connect(player_, SIGNAL(Paused()), SLOT(MediaPaused()));
connect(player_, SIGNAL(Playing()), SLOT(MediaPlaying()));
@ -265,6 +266,9 @@ MainWindow::MainWindow(QWidget *parent)
show();
library_->StartThreads();
player_->Init();
multi_loading_indicator_->TaskStarted("Loading audio engine");
}
MainWindow::~MainWindow() {
@ -543,3 +547,7 @@ void MainWindow::LibraryScanStarted() {
void MainWindow::LibraryScanFinished() {
multi_loading_indicator_->TaskFinished("Updating library");
}
void MainWindow::PlayerInitFinished() {
multi_loading_indicator_->TaskFinished("Loading audio engine");
}

View File

@ -69,6 +69,8 @@ class MainWindow : public QMainWindow {
void LibraryScanStarted();
void LibraryScanFinished();
void PlayerInitFinished();
private:
void SaveGeometry();

View File

@ -25,5 +25,19 @@ void MultiLoadingIndicator::TaskFinished(const QString &name) {
}
void MultiLoadingIndicator::UpdateText() {
ui_.text->setText(tasks_.join(", ") + "...");
QStringList strings;
foreach (QString task, tasks_) {
if (task.isEmpty())
continue;
task[0] = task[0].toLower();
strings << task;
}
QString text(strings.join(", "));
if (!text.isEmpty()) {
text[0] = text[0].toUpper();
}
ui_.text->setText(text + "...");
}

View File

@ -4,26 +4,46 @@
#include "lastfmservice.h"
#include <QtDebug>
#include <QtConcurrentRun>
#include <boost/bind.hpp>
Player::Player(Playlist* playlist, LastFMService* lastfm, QObject* parent)
: QObject(parent),
playlist_(playlist),
lastfm_(lastfm),
current_item_options_(PlaylistItem::Default),
engine_(new XineEngine)
engine_(new XineEngine),
init_engine_watcher_(new QFutureWatcher<bool>(this))
{
if (!engine_->init()) {
qFatal("Couldn't load engine");
settings_.beginGroup("Player");
connect(init_engine_watcher_, SIGNAL(finished()), SLOT(EngineInitFinished()));
connect(engine_, SIGNAL(error(QString)), SIGNAL(Error(QString)));
}
void Player::Init() {
init_engine_ = QtConcurrent::run(boost::bind(&EngineBase::init, engine_));
init_engine_watcher_->setFuture(init_engine_);
}
void Player::EngineInitFinished() {
if (init_engine_.result() == false) {
qFatal("Error initialising audio engine");
}
settings_.beginGroup("Player");
SetVolume(settings_.value("volume", 50).toInt());
SetVolumeInternal(settings_.value("volume", 50).toInt());
connect(engine_, SIGNAL(stateChanged(Engine::State)), SLOT(EngineStateChanged(Engine::State)));
connect(engine_, SIGNAL(trackEnded()), SLOT(TrackEnded()));
emit InitFinished();
}
void Player::ReloadSettings() {
if (!init_engine_.isFinished())
return;
engine_->reloadSettings();
}
@ -54,6 +74,9 @@ void Player::TrackEnded() {
}
void Player::PlayPause() {
if (!init_engine_.isFinished())
return;
switch (engine_->state()) {
case Engine::Paused:
qDebug() << "Unpausing";
@ -84,6 +107,9 @@ void Player::PlayPause() {
}
void Player::Stop() {
if (!init_engine_.isFinished())
return;
qDebug() << "Stopping";
engine_->stop();
playlist_->set_current_index(-1);
@ -110,9 +136,13 @@ void Player::EngineStateChanged(Engine::State state) {
}
void Player::SetVolume(int value) {
SetVolumeInternal(value);
emit VolumeChanged(value);
}
void Player::SetVolumeInternal(int value) {
settings_.setValue("volume", value);
engine_->setVolume(value);
emit VolumeChanged(value);
}
int Player::GetVolume() const {
@ -124,6 +154,9 @@ Engine::State Player::GetState() const {
}
void Player::PlayAt(int index) {
if (!init_engine_.isFinished())
return;
playlist_->set_current_index(index);
PlaylistItem* item = playlist_->item_at(index);
@ -141,6 +174,9 @@ void Player::PlayAt(int index) {
}
void Player::StreamReady(const QUrl& original_url, const QUrl& media_url) {
if (!init_engine_.isFinished())
return;
int current_index = playlist_->current_index();
if (current_index == -1)
return;
@ -155,5 +191,8 @@ void Player::StreamReady(const QUrl& original_url, const QUrl& media_url) {
}
void Player::Seek(int seconds) {
if (!init_engine_.isFinished())
return;
engine_->seek(seconds * 1000);
}

View File

@ -3,6 +3,8 @@
#include <QObject>
#include <QSettings>
#include <QFuture>
#include <QFutureWatcher>
#include "engine_fwd.h"
#include "playlistitem.h"
@ -18,6 +20,8 @@ class Player : public QObject {
public:
Player(Playlist* playlist, LastFMService* lastfm, QObject* parent = 0);
void Init();
EngineBase* GetEngine() { return engine_; }
Engine::State GetState() const;
int GetVolume() const;
@ -40,6 +44,8 @@ class Player : public QObject {
void StreamReady(const QUrl& original_url, const QUrl& media_url);
signals:
void InitFinished();
void Playing();
void Paused();
void Stopped();
@ -47,8 +53,12 @@ class Player : public QObject {
void Error(const QString& message);
private slots:
void EngineInitFinished();
void EngineStateChanged(Engine::State);
private:
void SetVolumeInternal(int value);
private:
Playlist* playlist_;
LastFMService* lastfm_;
@ -58,6 +68,8 @@ class Player : public QObject {
Song current_item_;
EngineBase* engine_;
QFuture<bool> init_engine_;
QFutureWatcher<bool>* init_engine_watcher_;
};
#endif // PLAYER_H

View File

@ -125,7 +125,7 @@ XineEngine::init()
m_xine = xine_new();
if( !m_xine ) {
QMessageBox::critical( 0, "Error", "Amarok could not initialize xine." );
emit error("Could not initialize xine.");
return false;
}
@ -153,7 +153,7 @@ XineEngine::makeNewStream()
m_audioPort = xine_open_audio_driver( m_xine, m_currentAudioPlugin.toLocal8Bit().constData(), NULL );
if( !m_audioPort ) {
//TODO make engine method that is the same but parents the dialog for us
QMessageBox::critical(0, "Error", "xine was unable to initialize any audio drivers." );
emit error("xine was unable to initialize any audio drivers.");
return false;
}
@ -161,7 +161,7 @@ XineEngine::makeNewStream()
if( !m_stream ) {
xine_close_audio_driver( m_xine, m_audioPort );
m_audioPort = NULL;
QMessageBox::critical(NULL, "Error", "Amarok could not create a new xine stream.");
emit error("Could not create a new xine stream");
return false;
}