Initialise gstreamer in the background instead of blocking the UI
This commit is contained in:
parent
c7472eda59
commit
75b70b4acb
|
@ -45,6 +45,7 @@
|
|||
#include <QCoreApplication>
|
||||
#include <QTimeLine>
|
||||
#include <QDir>
|
||||
#include <QtConcurrentRun>
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
|
@ -85,6 +86,8 @@ GstEngine::GstEngine()
|
|||
}
|
||||
|
||||
GstEngine::~GstEngine() {
|
||||
initialising_.waitForFinished();
|
||||
|
||||
current_pipeline_.reset();
|
||||
|
||||
// Destroy scope delay queue
|
||||
|
@ -135,18 +138,17 @@ bool GstEngine::Init() {
|
|||
SetEnv("GST_REGISTRY", registry_filename);
|
||||
}
|
||||
|
||||
// GStreamer initialization
|
||||
GError *err;
|
||||
if ( !gst_init_check( NULL, NULL, &err ) ) {
|
||||
qWarning("GStreamer could not be initialized");
|
||||
return false;
|
||||
}
|
||||
initialising_ = QtConcurrent::run(this, &GstEngine::InitialiseGstreamer);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GstEngine::InitialiseGstreamer() {
|
||||
gst_init(NULL, NULL);
|
||||
|
||||
#ifdef HAVE_IMOBILEDEVICE
|
||||
afcsrc_register_static();
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GstEngine::ReloadSettings() {
|
||||
|
@ -174,6 +176,8 @@ void GstEngine::ReloadSettings() {
|
|||
|
||||
|
||||
bool GstEngine::CanDecode(const QUrl &url) {
|
||||
initialising_.waitForFinished();
|
||||
|
||||
// We had some bug reports claiming that video files cause crashes in canDecode(),
|
||||
// so don't try to decode them
|
||||
if ( url.path().toLower().endsWith( ".mov" ) ||
|
||||
|
@ -400,6 +404,8 @@ void GstEngine::UpdateScope() {
|
|||
}
|
||||
|
||||
void GstEngine::StartPreloading(const QUrl& url) {
|
||||
initialising_.waitForFinished();
|
||||
|
||||
if (autocrossfade_enabled_) {
|
||||
// Have to create a new pipeline so we can crossfade between the two
|
||||
|
||||
|
@ -422,6 +428,8 @@ void GstEngine::StartPreloading(const QUrl& url) {
|
|||
}
|
||||
|
||||
bool GstEngine::Load(const QUrl& url, Engine::TrackChangeType change) {
|
||||
initialising_.waitForFinished();
|
||||
|
||||
Engine::Base::Load(url, change);
|
||||
|
||||
// Clementine just crashes when asked to load a file that doesn't exist on
|
||||
|
@ -495,6 +503,8 @@ void GstEngine::StartFadeout() {
|
|||
|
||||
|
||||
bool GstEngine::Play( uint offset ) {
|
||||
initialising_.waitForFinished();
|
||||
|
||||
QFuture<GstStateChangeReturn> future = current_pipeline_->SetState(GST_STATE_PLAYING);
|
||||
BoundFutureWatcher<GstStateChangeReturn, uint>* watcher =
|
||||
new BoundFutureWatcher<GstStateChangeReturn, uint>(offset, this);
|
||||
|
@ -708,6 +718,8 @@ GstElement* GstEngine::CreateElement(const QString& factoryName, GstElement* bin
|
|||
|
||||
GstEngine::PluginDetailsList
|
||||
GstEngine::GetPluginList(const QString& classname) const {
|
||||
const_cast<GstEngine*>(this)->initialising_.waitForFinished();
|
||||
|
||||
PluginDetailsList ret;
|
||||
|
||||
GstRegistry* registry = gst_registry_get_default();
|
||||
|
@ -733,6 +745,8 @@ GstEngine::PluginDetailsList
|
|||
}
|
||||
|
||||
shared_ptr<GstEnginePipeline> GstEngine::CreatePipeline() {
|
||||
initialising_.waitForFinished();
|
||||
|
||||
shared_ptr<GstEnginePipeline> ret(new GstEnginePipeline(this));
|
||||
ret->set_output_device(sink_, device_);
|
||||
ret->set_replaygain(rg_enabled_, rg_mode_, rg_preamp_, rg_compression_);
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "enginebase.h"
|
||||
#include "bufferconsumer.h"
|
||||
|
||||
#include <QFuture>
|
||||
#include <QHash>
|
||||
#include <QList>
|
||||
#include <QString>
|
||||
|
@ -130,6 +131,7 @@ class GstEngine : public Engine::Base, public BufferConsumer {
|
|||
|
||||
static void SetEnv(const char* key, const QString& value);
|
||||
PluginDetailsList GetPluginList(const QString& classname) const;
|
||||
void InitialiseGstreamer();
|
||||
|
||||
void StartFadeout();
|
||||
|
||||
|
@ -151,6 +153,8 @@ class GstEngine : public Engine::Base, public BufferConsumer {
|
|||
|
||||
static const char* kHypnotoadPipeline;
|
||||
|
||||
QFuture<void> initialising_;
|
||||
|
||||
QString sink_;
|
||||
QString device_;
|
||||
|
||||
|
|
|
@ -96,6 +96,8 @@
|
|||
|
||||
#include <cmath>
|
||||
|
||||
#include <QTime>
|
||||
|
||||
using boost::shared_ptr;
|
||||
using boost::scoped_ptr;
|
||||
|
||||
|
@ -148,13 +150,19 @@ MainWindow::MainWindow(NetworkAccessManager* network, Engine::Type engine, QWidg
|
|||
track_position_timer_(new QTimer(this)),
|
||||
was_maximized_(false)
|
||||
{
|
||||
QTime t;
|
||||
t.start();
|
||||
// Wait for the database thread to start - lots of stuff depends on it.
|
||||
database_->Start(true);
|
||||
|
||||
qDebug() << t.restart() << "database startup";
|
||||
|
||||
// Create some objects in the database thread
|
||||
playlist_backend_ = database_->CreateInThread<PlaylistBackend>();
|
||||
playlist_backend_->SetDatabase(database_->Worker());
|
||||
|
||||
qDebug() << t.restart() << "playlist backend";
|
||||
|
||||
// Create stuff that needs the database
|
||||
radio_model_ = new RadioModel(database_, network, task_manager_, this);
|
||||
player_ = new Player(playlists_, radio_model_->GetLastFMService(), engine, this);
|
||||
|
@ -164,6 +172,8 @@ MainWindow::MainWindow(NetworkAccessManager* network, Engine::Type engine, QWidg
|
|||
radio_model_->SetSettingsDialog(settings_dialog_.get());
|
||||
devices_ = new DeviceManager(database_, task_manager_, this),
|
||||
|
||||
qDebug() << t.restart() << "other shit";
|
||||
|
||||
// Initialise the UI
|
||||
ui_->setupUi(this);
|
||||
ui_->multi_loading_indicator->SetTaskManager(task_manager_);
|
||||
|
@ -177,9 +187,13 @@ MainWindow::MainWindow(NetworkAccessManager* network, Engine::Type engine, QWidg
|
|||
ui_->tabs->setDocumentMode(false);
|
||||
#endif
|
||||
|
||||
qDebug() << t.restart() << "ui";
|
||||
|
||||
// Start initialising the player
|
||||
player_->Init();
|
||||
|
||||
qDebug() << t.restart() << "player";
|
||||
|
||||
#ifdef HAVE_GSTREAMER
|
||||
if (GstEngine* engine = qobject_cast<GstEngine*>(player_->GetEngine())) {
|
||||
settings_dialog_->SetGstEngine(engine);
|
||||
|
@ -217,6 +231,8 @@ MainWindow::MainWindow(NetworkAccessManager* network, Engine::Type engine, QWidg
|
|||
|
||||
cover_manager_->Init();
|
||||
|
||||
qDebug() << t.restart() << "models";
|
||||
|
||||
// Icons
|
||||
ui_->action_about->setIcon(IconLoader::Load("help-about"));
|
||||
ui_->action_add_file->setIcon(IconLoader::Load("document-open"));
|
||||
|
@ -245,6 +261,8 @@ MainWindow::MainWindow(NetworkAccessManager* network, Engine::Type engine, QWidg
|
|||
ui_->action_update_library->setIcon(IconLoader::Load("view-refresh"));
|
||||
ui_->action_rain->setIcon(IconLoader::Load("weather-showers-scattered"));
|
||||
|
||||
qDebug() << t.restart() << "icons";
|
||||
|
||||
// File view connections
|
||||
connect(ui_->file_view, SIGNAL(AddToPlaylist(QList<QUrl>)), SLOT(AddFilesToPlaylist(QList<QUrl>)));
|
||||
connect(ui_->file_view, SIGNAL(Load(QList<QUrl>)), SLOT(LoadFilesToPlaylist(QList<QUrl>)));
|
||||
|
@ -416,6 +434,8 @@ MainWindow::MainWindow(NetworkAccessManager* network, Engine::Type engine, QWidg
|
|||
ui_->action_shuffle->setShortcut(QKeySequence());
|
||||
#endif
|
||||
|
||||
qDebug() << t.restart() << "connections";
|
||||
|
||||
playlist_delete_->setVisible(false); // TODO
|
||||
|
||||
connect(ui_->playlist, SIGNAL(UndoRedoActionsChanged(QAction*,QAction*)),
|
||||
|
@ -445,6 +465,8 @@ MainWindow::MainWindow(NetworkAccessManager* network, Engine::Type engine, QWidg
|
|||
connect(saved_radio, SIGNAL(ShowAddStreamDialog()),
|
||||
add_stream_dialog_.get(), SLOT(show()));
|
||||
|
||||
qDebug() << t.restart() << "more connections";
|
||||
|
||||
#ifdef Q_OS_DARWIN
|
||||
mac::SetApplicationHandler(this);
|
||||
#endif
|
||||
|
@ -477,6 +499,8 @@ MainWindow::MainWindow(NetworkAccessManager* network, Engine::Type engine, QWidg
|
|||
wiimotedev_shortcuts_ = new WiimotedevShortcuts(player_, this);
|
||||
#endif
|
||||
|
||||
qDebug() << t.restart() << "tray";
|
||||
|
||||
// Global shortcuts
|
||||
connect(global_shortcuts_, SIGNAL(Play()), player_, SLOT(Play()));
|
||||
connect(global_shortcuts_, SIGNAL(Pause()), player_, SLOT(Pause()));
|
||||
|
@ -539,13 +563,19 @@ MainWindow::MainWindow(NetworkAccessManager* network, Engine::Type engine, QWidg
|
|||
connect(ui_->action_hypnotoad, SIGNAL(toggled(bool)), ui_->now_playing, SLOT(AllHail(bool)));
|
||||
NowPlayingWidgetPositionChanged(ui_->now_playing->show_above_status_bar());
|
||||
|
||||
qDebug() << t.restart() << "stuff";
|
||||
|
||||
// Load theme
|
||||
StyleSheetLoader* css_loader = new StyleSheetLoader(this);
|
||||
css_loader->SetStyleSheet(this, ":mainwindow.css");
|
||||
|
||||
qDebug() << t.restart() << "theme";
|
||||
|
||||
// Load playlists
|
||||
playlists_->Init(library_->backend(), playlist_backend_, ui_->playlist_sequence);
|
||||
|
||||
qDebug() << t.restart() << "load playlists";
|
||||
|
||||
// Load settings
|
||||
settings_.beginGroup(kSettingsGroup);
|
||||
|
||||
|
@ -579,12 +609,16 @@ MainWindow::MainWindow(NetworkAccessManager* network, Engine::Type engine, QWidg
|
|||
show();
|
||||
#endif
|
||||
|
||||
qDebug() << t.restart() << "load settings";
|
||||
|
||||
QShortcut* close_window_shortcut = new QShortcut(this);
|
||||
close_window_shortcut->setKey(Qt::CTRL + Qt::Key_W);
|
||||
connect(close_window_shortcut, SIGNAL(activated()), SLOT(SetHiddenInTray()));
|
||||
|
||||
library_->Init();
|
||||
library_->StartThreads();
|
||||
|
||||
qDebug() << t.restart() << "start library";
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow() {
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
|
||||
SettingsDialog::SettingsDialog(QWidget* parent)
|
||||
: QDialog(parent),
|
||||
gst_engine_(NULL),
|
||||
ui_(new Ui_SettingsDialog),
|
||||
loading_settings_(false),
|
||||
pretty_popup_(new OSDPretty(OSDPretty::Mode_Draggable))
|
||||
|
@ -280,6 +281,22 @@ void SettingsDialog::showEvent(QShowEvent*) {
|
|||
QSettings s;
|
||||
loading_settings_ = true;
|
||||
|
||||
#ifdef HAVE_GSTREAMER
|
||||
if (ui_->gst_plugin->count() == 0 && gst_engine_) {
|
||||
GstEngine::PluginDetailsList list = gst_engine_->GetOutputsList();
|
||||
|
||||
ui_->gst_plugin->setItemData(0, GstEngine::kAutoSink);
|
||||
foreach (const GstEngine::PluginDetails& details, list) {
|
||||
if (details.name == "autoaudiosink")
|
||||
continue;
|
||||
|
||||
ui_->gst_plugin->addItem(details.long_name, details.name);
|
||||
}
|
||||
ui_->gst_group->setEnabled(true);
|
||||
ui_->replaygain_group->setEnabled(true);
|
||||
}
|
||||
#endif // HAVE_GSTREAMER
|
||||
|
||||
// Behaviour
|
||||
s.beginGroup(MainWindow::kSettingsGroup);
|
||||
ui_->b_show_tray_icon_->setChecked(s.value("showtray", true).toBool());
|
||||
|
@ -456,22 +473,6 @@ void SettingsDialog::ShowTrayIconToggled(bool on) {
|
|||
ui_->b_remember_->setChecked(true);
|
||||
}
|
||||
|
||||
#ifdef HAVE_GSTREAMER
|
||||
void SettingsDialog::SetGstEngine(const GstEngine *engine) {
|
||||
GstEngine::PluginDetailsList list = engine->GetOutputsList();
|
||||
|
||||
ui_->gst_plugin->setItemData(0, GstEngine::kAutoSink);
|
||||
foreach (const GstEngine::PluginDetails& details, list) {
|
||||
if (details.name == "autoaudiosink")
|
||||
continue;
|
||||
|
||||
ui_->gst_plugin->addItem(details.long_name, details.name);
|
||||
}
|
||||
ui_->gst_group->setEnabled(true);
|
||||
ui_->replaygain_group->setEnabled(true);
|
||||
}
|
||||
#endif // HAVE_GSTREAMER
|
||||
|
||||
void SettingsDialog::GstPluginChanged(int index) {
|
||||
#ifdef HAVE_GSTREAMER
|
||||
QString name = ui_->gst_plugin->itemData(index).toString();
|
||||
|
|
|
@ -31,9 +31,7 @@ class Ui_SettingsDialog;
|
|||
class WiimotedevShortcutsConfig;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GSTREAMER
|
||||
class GstEngine;
|
||||
#endif
|
||||
class GstEngine;
|
||||
|
||||
class SettingsDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
|
@ -57,9 +55,7 @@ class SettingsDialog : public QDialog {
|
|||
|
||||
void SetLibraryDirectoryModel(LibraryDirectoryModel* model);
|
||||
void SetGlobalShortcutManager(GlobalShortcuts* manager);
|
||||
#ifdef HAVE_GSTREAMER
|
||||
void SetGstEngine(const GstEngine* engine);
|
||||
#endif
|
||||
void SetGstEngine(const GstEngine* engine) { gst_engine_ = engine; }
|
||||
|
||||
void OpenAtPage(Page page);
|
||||
|
||||
|
@ -90,6 +86,8 @@ class SettingsDialog : public QDialog {
|
|||
#ifdef ENABLE_WIIMOTEDEV
|
||||
WiimotedevShortcutsConfig* wiimotedev_config_;
|
||||
#endif
|
||||
const GstEngine* gst_engine_;
|
||||
|
||||
Ui_SettingsDialog* ui_;
|
||||
|
||||
bool loading_settings_;
|
||||
|
|
Loading…
Reference in New Issue