1
0
mirror of https://github.com/clementine-player/Clementine synced 2025-02-07 14:43:37 +01:00

Add a UI for choosing which gstreamer audio sink to use

This commit is contained in:
David Sansome 2010-04-07 13:51:14 +00:00
parent f8240e8b7c
commit 256648f5e3
15 changed files with 203 additions and 1881 deletions

View File

@ -257,6 +257,9 @@ namespace Engine
static const char* kSettingsGroup;
public slots:
virtual void ReloadSettings() {}
protected:
Base();

View File

@ -32,6 +32,7 @@
#include <QRegExp>
#include <QFile>
#include <QMessageBox>
#include <QSettings>
#include <QtDebug>
#include <gst/gst.h>
@ -42,7 +43,9 @@
using std::vector;
GstEngine* GstEngine::sInstance;
GstEngine* GstEngine::sInstance = NULL;
const char* GstEngine::kSettingsGroup = "GstEngine";
const char* GstEngine::kAutoSink = "autoaudiosink";
/////////////////////////////////////////////////////////////////////////////////////
@ -61,7 +64,7 @@ gboolean GstEngine::BusCallback(GstBus*, GstMessage* msg, gpointer) {
instance()->gst_error_ = QString::fromAscii( error->message );
instance()->gst_debug_ = QString::fromAscii( debugs );
QTimer::singleShot( 0, instance(), SLOT( handlePipelineError() ) );
QMetaObject::invokeMethod(instance(), "HandlePipelineError", Qt::QueuedConnection);
break;
}
@ -176,6 +179,7 @@ GstEngine::GstEngine()
can_decode_src_(NULL),
can_decode_bin_(NULL)
{
ReloadSettings();
}
GstEngine::~GstEngine() {
@ -220,6 +224,13 @@ bool GstEngine::init() {
return true;
}
void GstEngine::ReloadSettings() {
QSettings s;
s.beginGroup(kSettingsGroup);
sink_ = s.value("sink", kAutoSink).toString();
}
bool GstEngine::canDecode(const QUrl &url) {
// We had some bug reports claiming that video files cause crashes in canDecode(),
@ -714,38 +725,41 @@ GstElement* GstEngine::CreateElement(
}
QStringList GstEngine::GetPluginList( const QString& classname ) const {
GList* features = NULL;
QString name;
QStringList results;
GstEngine::PluginDetailsList
GstEngine::GetPluginList(const QString& classname) const {
PluginDetailsList ret;
GstRegistry* registry = gst_registry_get_default();
features = gst_registry_get_feature_list(registry,GST_TYPE_ELEMENT_FACTORY);
while ( features ) {
GstElementFactory * factory = GST_ELEMENT_FACTORY ( features->data );
if ( g_strrstr ( factory->details.klass, classname.toAscii().constData() ) ) {
name = g_strdup ( GST_PLUGIN_FEATURE_NAME ( features->data ) );
if ( name != "autoaudiosink" )
results << name;
GList* features =
gst_registry_get_feature_list(registry, GST_TYPE_ELEMENT_FACTORY);
while (features) {
GstElementFactory* factory = GST_ELEMENT_FACTORY(features->data);
if (QString(factory->details.klass).contains(classname)) {
PluginDetails details;
details.name = QString::fromUtf8(GST_PLUGIN_FEATURE_NAME(features->data));
details.long_name = QString::fromUtf8(factory->details.longname);
details.description = QString::fromUtf8(factory->details.description);
details.author = QString::fromUtf8(factory->details.author);
ret << details;
}
features = g_list_next ( features );
}
gst_plugin_feature_list_free(features);
return results;
return ret;
}
bool GstEngine::CreatePipeline() {
DestroyPipeline();
QString output = "autoaudiosink";
gst_pipeline_ = gst_pipeline_new( "pipeline" );
gst_audiobin_ = gst_bin_new( "audiobin" );
if ( !( gst_audiosink_ = CreateElement( output, gst_audiobin_ ) ) ) {
QTimer::singleShot( 0, this, SLOT( errorNoOutput() ) );
if ( !( gst_audiosink_ = CreateElement( sink_, gst_audiobin_ ) ) ) {
QMetaObject::invokeMethod(this, "ErrorNoOutput", Qt::QueuedConnection);
return false;
}

View File

@ -50,6 +50,17 @@ class GstEngine : public Engine::Base {
GstEngine();
~GstEngine();
struct PluginDetails {
QString name;
QString long_name;
QString author;
QString description;
};
typedef QList<PluginDetails> PluginDetailsList;
static const char* kSettingsGroup;
static const char* kAutoSink;
bool init();
bool canDecode(const QUrl& url);
@ -64,6 +75,8 @@ class GstEngine : public Engine::Base {
void gstStatusText(const QString& str) { emit statusText( str ); }
void gstMetaData(Engine::SimpleMetaBundle &bundle) { emit metaData( bundle ); }
PluginDetailsList GetOutputsList() const { return GetPluginList( "Sink/Audio" ); }
public slots:
bool load(const QUrl&, bool stream);
bool play(uint offset);
@ -78,6 +91,8 @@ class GstEngine : public Engine::Base {
/** Set equalizer preamp and gains, range -100..100. Gains are 10 values. */
void setEqualizerParameters(int preamp, const QList<int>& bandGains);
void ReloadSettings();
protected:
void setVolumeSW(uint percent);
void timerEvent(QTimerEvent*);
@ -105,12 +120,6 @@ class GstEngine : public Engine::Base {
static GstElement* CreateElement(
const QString& factoryName, GstElement* bin = 0, const QString& name = 0);
/**
* Fetches a list of available output sink plugins
* @return List of output sinks
*/
QStringList GetOutputsList() const { return GetPluginList( "Sink/Audio" ); }
// CALLBACKS:
/** Bus message */
//static GstBusSyncReply bus_cb( GstBus*, GstMessage*, gpointer );
@ -127,7 +136,7 @@ class GstEngine : public Engine::Base {
static void HandoffCallback( GstPad*, GstBuffer*, gpointer );
/** Get a list of available plugins from a specified Class */
QStringList GetPluginList(const QString& classname) const;
PluginDetailsList GetPluginList(const QString& classname) const;
/** Construct the output pipeline */
bool CreatePipeline();
@ -148,6 +157,8 @@ class GstEngine : public Engine::Base {
static const int kTimerInterval = 40; //msec
static const int kGstStateTimeout = 10000000;
QString sink_;
static GstEngine* sInstance;
GstElement* gst_pipeline_;

View File

@ -38,6 +38,7 @@
#include "xspfparser.h"
#include "playlistsequence.h"
#include "groupbydialog.h"
#include "engines/gstengine.h"
#include "globalshortcuts/globalshortcuts.h"
@ -96,6 +97,9 @@ MainWindow::MainWindow(QNetworkAccessManager* network, QWidget *parent)
// Start initialising the player
player_->Init();
if (GstEngine* engine = qobject_cast<GstEngine*>(player_->GetEngine()))
settings_dialog_->SetGstEngine(engine);
// Models
library_sort_model_->setSourceModel(library_);
library_sort_model_->setSortRole(Library::Role_SortText);
@ -327,6 +331,7 @@ MainWindow::MainWindow(QNetworkAccessManager* network, QWidget *parent)
connect(settings_dialog_, SIGNAL(accepted()), player_, SLOT(ReloadSettings()));
connect(settings_dialog_, SIGNAL(accepted()), osd_, SLOT(ReloadSettings()));
connect(settings_dialog_, SIGNAL(accepted()), ui_.library_view, SLOT(ReloadSettings()));
connect(settings_dialog_, SIGNAL(accepted()), player_->GetEngine(), SLOT(ReloadSettings()));
// Add stream dialog
connect(add_stream_dialog_, SIGNAL(accepted()), SLOT(AddStreamAccepted()));

View File

@ -19,6 +19,7 @@
#include "osd.h"
#include "osdpretty.h"
#include "mainwindow.h"
#include "engines/gstengine.h"
#include <QSettings>
#include <QColorDialog>
@ -113,6 +114,10 @@ void SettingsDialog::accept() {
s.setValue("FadeoutDuration", ui_.fadeout_duration->value());
s.endGroup();
s.beginGroup(GstEngine::kSettingsGroup);
s.setValue("sink", ui_.gst_plugin->itemData(ui_.gst_plugin->currentIndex()).toString());
s.endGroup();
// Notifications
OSD::Behaviour osd_behaviour;
if (ui_.notifications_none->isChecked()) osd_behaviour = OSD::Disabled;
@ -168,6 +173,17 @@ void SettingsDialog::showEvent(QShowEvent*) {
ui_.fadeout_duration->setValue(s.value("FadeoutDuration", 2000).toInt());
s.endGroup();
s.beginGroup(GstEngine::kSettingsGroup);
QString sink = s.value("sink", GstEngine::kAutoSink).toString();
ui_.gst_plugin->setCurrentIndex(0);
for (int i=0 ; i<ui_.gst_plugin->count() ; ++i) {
if (ui_.gst_plugin->itemData(i).toString() == sink) {
ui_.gst_plugin->setCurrentIndex(i);
break;
}
}
s.endGroup();
// Notifications
s.beginGroup(OSD::kSettingsGroup);
OSD::Behaviour osd_behaviour = OSD::Behaviour(s.value("Behaviour", OSD::Native).toInt());
@ -282,3 +298,16 @@ void SettingsDialog::ShowTrayIconToggled(bool on) {
if (!on && ui_.b_always_hide_->isChecked())
ui_.b_remember_->setChecked(true);
}
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);
}

View File

@ -23,6 +23,7 @@
class LibraryDirectoryModel;
class OSDPretty;
class GstEngine;
class SettingsDialog : public QDialog {
Q_OBJECT
@ -32,6 +33,7 @@ class SettingsDialog : public QDialog {
~SettingsDialog();
void SetLibraryDirectoryModel(LibraryDirectoryModel* model);
void SetGstEngine(const GstEngine* engine);
// QDialog
void accept();

View File

@ -108,7 +108,7 @@
<item>
<widget class="QStackedWidget" name="stacked_widget">
<property name="currentIndex">
<number>1</number>
<number>0</number>
</property>
<widget class="QWidget" name="playback_page">
<layout class="QVBoxLayout" name="verticalLayout_2">
@ -187,6 +187,34 @@
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="gst_group">
<property name="enabled">
<bool>false</bool>
</property>
<property name="title">
<string>GStreamer audio engine</string>
</property>
<layout class="QFormLayout" name="formLayout_3">
<item row="0" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Output plugin</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="gst_plugin">
<item>
<property name="text">
<string>Choose automatically</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -620,6 +620,15 @@ msgstr ""
msgid " ms"
msgstr ""
msgid "GStreamer audio engine"
msgstr ""
msgid "Output plugin"
msgstr ""
msgid "Choose automatically"
msgstr ""
msgid "Show tray icon"
msgstr ""