More engine fixes
This commit is contained in:
@@ -35,7 +35,7 @@
|
||||
#include "core/logging.h"
|
||||
|
||||
DirectSoundDeviceFinder::DirectSoundDeviceFinder()
|
||||
: DeviceFinder("directsound", { "directsound", "dsound", "directsoundsink" }) {
|
||||
: DeviceFinder("directsound", { "directsound", "dsound", "directsoundsink", "directx", "directx2" }) {
|
||||
}
|
||||
|
||||
QList<DeviceFinder::Device> DirectSoundDeviceFinder::ListDevices() {
|
||||
|
||||
@@ -84,7 +84,6 @@ bool Engine::Base::Play(const QUrl &url, TrackChangeFlags flags, bool force_stop
|
||||
void Engine::Base::SetVolume(uint value) {
|
||||
|
||||
volume_ = value;
|
||||
|
||||
SetVolumeSW(MakeVolumeLogarithmic(value));
|
||||
|
||||
}
|
||||
@@ -132,3 +131,9 @@ void Engine::Base::EmitAboutToEnd() {
|
||||
about_to_end_emitted_ = true;
|
||||
emit TrackAboutToEnd();
|
||||
}
|
||||
|
||||
bool Engine::Base::ValidOutput(const QString &output) {
|
||||
|
||||
return (true);
|
||||
|
||||
}
|
||||
|
||||
@@ -89,8 +89,9 @@ public:
|
||||
}
|
||||
|
||||
virtual OutputDetailsList GetOutputsList() const = 0;
|
||||
virtual bool ValidOutput(const QString &output) = 0;
|
||||
virtual QString DefaultOutput() = 0;
|
||||
virtual bool CustomDeviceSupport(const QString &name) = 0;
|
||||
virtual bool CustomDeviceSupport(const QString &output) = 0;
|
||||
|
||||
// Plays a media stream represented with the URL 'u' from the given 'beginning' to the given 'end' (usually from 0 to a song's length).
|
||||
// Both markers should be passed in nanoseconds. 'end' can be negative, indicating that the real length of 'u' stream is unknown.
|
||||
|
||||
@@ -99,6 +99,7 @@ GstEngine::GstEngine(TaskManager *task_manager)
|
||||
scope_chunk_(0),
|
||||
have_new_buffer_(false) {
|
||||
|
||||
type_ = Engine::GStreamer;
|
||||
seek_timer_->setSingleShot(true);
|
||||
seek_timer_->setInterval(kSeekDelayNanosec / kNsecPerMsec);
|
||||
connect(seek_timer_, SIGNAL(timeout()), SLOT(SeekNow()));
|
||||
@@ -129,7 +130,6 @@ bool GstEngine::Init() {
|
||||
|
||||
SetEnvironment();
|
||||
|
||||
type_ = Engine::GStreamer;
|
||||
initialising_ = QtConcurrent::run(this, &GstEngine::InitialiseGStreamer);
|
||||
return true;
|
||||
|
||||
@@ -388,8 +388,19 @@ EngineBase::OutputDetailsList GstEngine::GetOutputsList() const {
|
||||
|
||||
}
|
||||
|
||||
bool GstEngine::CustomDeviceSupport(const QString &name) {
|
||||
return (name == kALSASink || name == kOpenALSASink || name == kOSSSink || name == kOSS4Sink || name == kPulseSink || name == kA2DPSink || name == kAVDTPSink);
|
||||
bool GstEngine::ValidOutput(const QString &output) {
|
||||
|
||||
PluginDetailsList plugins = GetPluginList("Sink/Audio");
|
||||
for (const PluginDetails &plugin : plugins) {
|
||||
if (plugin.name == output) return(true);
|
||||
}
|
||||
return(false);
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool GstEngine::CustomDeviceSupport(const QString &output) {
|
||||
return (output == kALSASink || output == kOpenALSASink || output == kOSSSink || output == kOSS4Sink || output == kPulseSink || output == kA2DPSink || output == kAVDTPSink);
|
||||
}
|
||||
|
||||
void GstEngine::ReloadSettings() {
|
||||
|
||||
@@ -84,8 +84,9 @@ class GstEngine : public Engine::Base, public GstBufferConsumer {
|
||||
const Engine::Scope &scope(int chunk_length);
|
||||
|
||||
OutputDetailsList GetOutputsList() const;
|
||||
bool ValidOutput(const QString &output);
|
||||
QString DefaultOutput() { return kAutoSink; }
|
||||
bool CustomDeviceSupport(const QString &name);
|
||||
bool CustomDeviceSupport(const QString &output);
|
||||
|
||||
void EnsureInitialised() { initialising_.waitForFinished(); }
|
||||
void InitialiseGStreamer();
|
||||
@@ -132,7 +133,6 @@ class GstEngine : public Engine::Base, public GstBufferConsumer {
|
||||
void BufferingFinished();
|
||||
|
||||
private:
|
||||
|
||||
static const char *kAutoSink;
|
||||
static const char *kALSASink;
|
||||
static const char *kOpenALSASink;
|
||||
|
||||
@@ -32,11 +32,13 @@
|
||||
#include "core/logging.h"
|
||||
|
||||
PhononEngine::PhononEngine(TaskManager *task_manager)
|
||||
: media_object_(new Phonon::MediaObject(this)),
|
||||
: EngineBase(),
|
||||
media_object_(new Phonon::MediaObject(this)),
|
||||
audio_output_(new Phonon::AudioOutput(Phonon::MusicCategory, this)),
|
||||
state_timer_(new QTimer(this)),
|
||||
seek_offset_(-1)
|
||||
{
|
||||
seek_offset_(-1) {
|
||||
|
||||
type_ = Engine::Phonon;
|
||||
|
||||
Phonon::createPath(media_object_, audio_output_);
|
||||
|
||||
@@ -54,8 +56,6 @@ PhononEngine::~PhononEngine() {
|
||||
}
|
||||
|
||||
bool PhononEngine::Init() {
|
||||
//qLog(Debug) << __PRETTY_FUNCTION__;
|
||||
type_ = Engine::Phonon;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -179,6 +179,13 @@ EngineBase::OutputDetailsList PhononEngine::GetOutputsList() const {
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool PhononEngine::CustomDeviceSupport(const QString &name) {
|
||||
bool PhononEngine::ValidOutput(const QString &output) {
|
||||
|
||||
return (output == "auto" || output == "" || output == DefaultOutput);
|
||||
return(false);
|
||||
|
||||
}
|
||||
|
||||
bool PhononEngine::CustomDeviceSupport(const QString &output) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -64,7 +64,8 @@ class PhononEngine : public Engine::Base {
|
||||
qint64 length_nanosec() const;
|
||||
|
||||
QString DefaultOutput() { return ""; }
|
||||
bool CustomDeviceSupport(const QString &name);
|
||||
bool ValidOutput(const QString &output);
|
||||
bool CustomDeviceSupport(const QString &output);
|
||||
|
||||
protected:
|
||||
void SetVolumeSW( uint percent );
|
||||
|
||||
@@ -40,13 +40,14 @@
|
||||
VLCEngine *VLCEngine::sInstance = nullptr;
|
||||
|
||||
VLCEngine::VLCEngine(TaskManager *task_manager)
|
||||
: instance_(nullptr),
|
||||
: EngineBase(),
|
||||
instance_(nullptr),
|
||||
player_(nullptr),
|
||||
state_(Engine::Empty),
|
||||
scope_data_(4096)
|
||||
{
|
||||
scope_data_(4096) {
|
||||
|
||||
Init();
|
||||
type_ = Engine::VLC;
|
||||
ReloadSettings();
|
||||
|
||||
}
|
||||
|
||||
@@ -61,8 +62,6 @@ VLCEngine::~VLCEngine() {
|
||||
|
||||
bool VLCEngine::Init() {
|
||||
|
||||
type_ = Engine::VLC;
|
||||
|
||||
/* FIXME: Do we need this?
|
||||
static const char *const args[] = {
|
||||
"-I", "dummy", // Don't use any interface
|
||||
@@ -113,8 +112,15 @@ bool VLCEngine::Init() {
|
||||
|
||||
}
|
||||
|
||||
bool VLCEngine::Load(const QUrl &url, Engine::TrackChangeFlags change, bool force_stop_at_end, quint64 beginning_nanosec, qint64 end_nanosec) {
|
||||
bool VLCEngine::Initialised() const {
|
||||
|
||||
if (instance_ && player_) return true;
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
bool VLCEngine::Load(const QUrl &url, Engine::TrackChangeFlags change, bool force_stop_at_end, quint64 beginning_nanosec, qint64 end_nanosec) {
|
||||
if (!Initialised()) return false;
|
||||
// Create the media object
|
||||
VlcScopedRef<libvlc_media_t> media(libvlc_media_new_location(instance_, url.toEncoded().constData()));
|
||||
|
||||
@@ -125,7 +131,7 @@ bool VLCEngine::Load(const QUrl &url, Engine::TrackChangeFlags change, bool forc
|
||||
}
|
||||
|
||||
bool VLCEngine::Play(quint64 offset_nanosec) {
|
||||
|
||||
if (!Initialised()) return false;
|
||||
// Set audio output
|
||||
if (!output_.isEmpty() || output_ != "auto") {
|
||||
int result = libvlc_audio_output_set(player_, output_.toUtf8().constData());
|
||||
@@ -148,27 +154,29 @@ bool VLCEngine::Play(quint64 offset_nanosec) {
|
||||
}
|
||||
|
||||
void VLCEngine::Stop(bool stop_after) {
|
||||
|
||||
if (!Initialised()) return;
|
||||
libvlc_media_player_stop(player_);
|
||||
HandleErrors();
|
||||
|
||||
}
|
||||
|
||||
void VLCEngine::Pause() {
|
||||
|
||||
if (!Initialised()) return;
|
||||
libvlc_media_player_pause(player_);
|
||||
HandleErrors();
|
||||
|
||||
}
|
||||
|
||||
void VLCEngine::Unpause() {
|
||||
|
||||
if (!Initialised()) return;
|
||||
libvlc_media_player_play(player_);
|
||||
HandleErrors();
|
||||
|
||||
}
|
||||
|
||||
void VLCEngine::Seek(quint64 offset_nanosec) {
|
||||
|
||||
if (!Initialised()) return;
|
||||
|
||||
int offset = (offset_nanosec / kNsecPerMsec);
|
||||
|
||||
@@ -183,7 +191,7 @@ void VLCEngine::Seek(quint64 offset_nanosec) {
|
||||
}
|
||||
|
||||
void VLCEngine::SetVolumeSW(uint percent) {
|
||||
|
||||
if (!Initialised()) return;
|
||||
libvlc_audio_set_volume(player_, percent);
|
||||
HandleErrors();
|
||||
}
|
||||
@@ -248,12 +256,24 @@ EngineBase::OutputDetailsList VLCEngine::GetOutputsList() const {
|
||||
|
||||
}
|
||||
|
||||
bool VLCEngine::CustomDeviceSupport(const QString &name) {
|
||||
return (name == "auto" ? false : true);
|
||||
bool VLCEngine::ValidOutput(const QString &output) {
|
||||
|
||||
PluginDetailsList plugins = GetPluginList();
|
||||
for (const PluginDetails &plugin : plugins) {
|
||||
if (plugin.name == output) return(true);
|
||||
}
|
||||
return(false);
|
||||
|
||||
}
|
||||
|
||||
bool VLCEngine::CustomDeviceSupport(const QString &output) {
|
||||
return (output == "auto" ? false : true);
|
||||
}
|
||||
|
||||
uint VLCEngine::position() const {
|
||||
|
||||
if (!Initialised()) return (0);
|
||||
|
||||
bool is_playing = libvlc_media_player_is_playing(player_);
|
||||
HandleErrors();
|
||||
|
||||
@@ -268,6 +288,8 @@ uint VLCEngine::position() const {
|
||||
|
||||
uint VLCEngine::length() const {
|
||||
|
||||
if (!Initialised()) return(0);
|
||||
|
||||
bool is_playing = libvlc_media_player_is_playing(player_);
|
||||
HandleErrors();
|
||||
|
||||
|
||||
@@ -63,8 +63,9 @@ class VLCEngine : public Engine::Base {
|
||||
const Engine::Scope& Scope();
|
||||
|
||||
OutputDetailsList GetOutputsList() const;
|
||||
bool ValidOutput(const QString &output);
|
||||
QString DefaultOutput() { return ""; }
|
||||
bool CustomDeviceSupport(const QString &name);
|
||||
bool CustomDeviceSupport(const QString &value);
|
||||
|
||||
private:
|
||||
libvlc_instance_t *instance_;
|
||||
@@ -75,6 +76,7 @@ class VLCEngine : public Engine::Base {
|
||||
static VLCEngine *sInstance;
|
||||
QMutex scope_mutex_;
|
||||
|
||||
bool Initialised() const;
|
||||
uint position() const;
|
||||
uint length() const;
|
||||
bool CanDecode(const QUrl &url);
|
||||
|
||||
@@ -65,12 +65,8 @@ using std::shared_ptr;
|
||||
#define LLONG_MAX 9223372036854775807LL
|
||||
#endif
|
||||
|
||||
|
||||
//define this to use xine in a more standard way
|
||||
//#ifdef Q_OS_WIN32
|
||||
// Define this to use xine in a more standard way
|
||||
//#define XINE_SAFE_MODE
|
||||
//#endif
|
||||
|
||||
|
||||
const char *XineEngine::kAutoOutput = "auto";
|
||||
int XineEngine::last_error_ = XINE_MSG_NO_ERROR;
|
||||
@@ -88,56 +84,28 @@ XineEngine::XineEngine(TaskManager *task_manager)
|
||||
fadeout_running_ (false),
|
||||
prune_(nullptr) {
|
||||
|
||||
type_ = Engine::Xine;
|
||||
ReloadSettings();
|
||||
|
||||
}
|
||||
|
||||
XineEngine::~XineEngine() {
|
||||
|
||||
// Wait until the fader thread is done
|
||||
if (s_fader_) {
|
||||
stop_fader_ = true;
|
||||
s_fader_->resume(); // safety call if the engine is in the pause state
|
||||
s_fader_->wait();
|
||||
}
|
||||
|
||||
// Wait until the prune scope thread is done
|
||||
if (prune_) {
|
||||
prune_->exit();
|
||||
prune_->wait();
|
||||
}
|
||||
|
||||
s_fader_.reset();
|
||||
s_outfader_.reset();
|
||||
prune_.reset();
|
||||
|
||||
if (fadeout_enabled_) {
|
||||
bool terminateFader = false;
|
||||
FadeOut(fadeout_duration_, &terminateFader, true); // true == exiting
|
||||
}
|
||||
|
||||
if (stream_) xine_close(stream_);
|
||||
if (eventqueue_) xine_event_dispose_queue(eventqueue_);
|
||||
if (stream_) xine_dispose(stream_);
|
||||
if (audioport_) xine_close_audio_driver(xine_, audioport_);
|
||||
if (post_) xine_post_dispose(xine_, post_);
|
||||
if (xine_) xine_exit(xine_);
|
||||
|
||||
//qLog(Debug) << "xine closed";
|
||||
//qLog(Debug) << "Scope statistics:";
|
||||
//qLog(Debug) << "Average list size: " << log_buffer_count_ / log_scope_call_count_;
|
||||
//qLog(Debug) << "Buffer failure: " << double(log_no_suitable_buffer_*100) / log_scope_call_count_ << "%";
|
||||
Cleanup();
|
||||
|
||||
}
|
||||
|
||||
bool XineEngine::Init() {
|
||||
|
||||
type_ = Engine::Xine;
|
||||
|
||||
Cleanup();
|
||||
SetEnvironment();
|
||||
|
||||
QMutexLocker l(&init_mutex_);
|
||||
|
||||
xine_ = xine_new();
|
||||
if (!xine_) {
|
||||
emit Error("Could not initialize xine.");
|
||||
@@ -147,17 +115,76 @@ bool XineEngine::Init() {
|
||||
#ifdef XINE_SAFE_MODE
|
||||
xine_engine_set_param(xine_, XINE_ENGINE_PARAM_VERBOSITY, 99);
|
||||
#endif
|
||||
|
||||
xine_init(xine_);
|
||||
|
||||
MakeNewStream();
|
||||
xine_init(xine_);
|
||||
|
||||
#ifndef XINE_SAFE_MODE
|
||||
prune_.reset(new PruneScopeThread(this));
|
||||
prune_->start();
|
||||
#endif
|
||||
|
||||
SetDevice();
|
||||
|
||||
if (!ValidOutput(output_)) {
|
||||
qLog(Error) << "Invalid output detected:" << output_ << " - Resetting to default.";
|
||||
output_ = DefaultOutput();
|
||||
}
|
||||
audioport_ = xine_open_audio_driver(xine_, (output_.isEmpty() || output_ == kAutoOutput ? nullptr : output_.toUtf8().constData()), nullptr);
|
||||
if (!audioport_) {
|
||||
emit Error("Xine was unable to initialize any audio drivers.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
void XineEngine::Cleanup() {
|
||||
|
||||
// Wait until the prune scope thread is done
|
||||
if (prune_) {
|
||||
prune_->exit();
|
||||
prune_->wait();
|
||||
}
|
||||
prune_.reset();
|
||||
|
||||
// Wait until the fader thread is done
|
||||
if (s_fader_) {
|
||||
stop_fader_ = true;
|
||||
s_fader_->resume(); // safety call if the engine is in the pause state
|
||||
s_fader_->wait();
|
||||
}
|
||||
|
||||
s_fader_.reset();
|
||||
s_outfader_.reset();
|
||||
|
||||
if (stream_)
|
||||
xine_close(stream_);
|
||||
if (eventqueue_) {
|
||||
xine_event_dispose_queue(eventqueue_);
|
||||
eventqueue_ = nullptr;
|
||||
}
|
||||
if (stream_) {
|
||||
xine_dispose(stream_);
|
||||
stream_ = nullptr;
|
||||
}
|
||||
if (audioport_) {
|
||||
xine_close_audio_driver(xine_, audioport_);
|
||||
audioport_ = nullptr;
|
||||
}
|
||||
if (post_) {
|
||||
xine_post_dispose(xine_, post_);
|
||||
post_ = nullptr;
|
||||
}
|
||||
|
||||
if (xine_) xine_exit(xine_);
|
||||
xine_ = nullptr;
|
||||
|
||||
//qLog(Debug) << "xine closed";
|
||||
//qLog(Debug) << "Scope statistics:";
|
||||
//qLog(Debug) << "Average list size: " << log_buffer_count_ / log_scope_call_count_;
|
||||
//qLog(Debug) << "Buffer failure: " << double(log_no_suitable_buffer_*100) / log_scope_call_count_ << "%";
|
||||
|
||||
}
|
||||
|
||||
Engine::State XineEngine::state() const {
|
||||
@@ -183,7 +210,7 @@ bool XineEngine::Load(const QUrl &url, Engine::TrackChangeFlags change, bool for
|
||||
|
||||
if (s_outfader_) {
|
||||
s_outfader_->finish();
|
||||
if (s_outfader_) s_outfader_.reset();
|
||||
s_outfader_.reset();
|
||||
}
|
||||
|
||||
if (fade_length_ > 0 && xine_get_status(stream_) == XINE_STATUS_PLAY && url.scheme().toLower() == "file" && xine_get_param(stream_, XINE_PARAM_SPEED) != XINE_SPEED_PAUSE && (fade_next_track_ || crossfade_enabled_)) {
|
||||
@@ -370,14 +397,22 @@ EngineBase::OutputDetailsList XineEngine::GetOutputsList() const {
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool XineEngine::CustomDeviceSupport(const QString &name) {
|
||||
return (name == "alsa" || name == "oss" || name == "jack" || name == "pulseaudio");
|
||||
bool XineEngine::ValidOutput(const QString &output) {
|
||||
|
||||
PluginDetailsList plugins = GetPluginList();
|
||||
for (const PluginDetails &plugin : plugins) {
|
||||
if (plugin.name == output) return(true);
|
||||
}
|
||||
return(false);
|
||||
|
||||
}
|
||||
|
||||
bool XineEngine::CustomDeviceSupport(const QString &output) {
|
||||
return (output == "alsa" || output == "oss" || output == "jack" || output == "pulseaudio");
|
||||
}
|
||||
|
||||
void XineEngine::ReloadSettings() {
|
||||
|
||||
QSettings s;
|
||||
|
||||
Engine::Base::ReloadSettings();
|
||||
|
||||
if (output_ == "") output_ = DefaultOutput();
|
||||
@@ -386,13 +421,13 @@ void XineEngine::ReloadSettings() {
|
||||
|
||||
void XineEngine::SetEnvironment() {
|
||||
|
||||
#ifdef Q_OS_WIN32
|
||||
putenv(QString("XINE_PLUGIN_PATH=" + QCoreApplication::applicationDirPath() + "/xine/plugins").toLatin1().constData());
|
||||
#endif // Q_OS_WIN32
|
||||
#ifdef Q_OS_WIN
|
||||
putenv(QString("XINE_PLUGIN_PATH=" + QCoreApplication::applicationDirPath() + "/xine-plugins").toLatin1().constData());
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_DARWIN
|
||||
setenv("XINE_PLUGIN_PATH", QString(QCoreApplication::applicationDirPath() + "/../PlugIns/xine").toLatin1().constData(), 1);
|
||||
#endif // Q_OS_DARWIN
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
@@ -868,7 +903,7 @@ Engine::SimpleMetaBundle XineEngine::fetchMetaData() const {
|
||||
|
||||
}
|
||||
|
||||
bool XineEngine::MakeNewStream() {
|
||||
void XineEngine::SetDevice() {
|
||||
|
||||
if (device_.isValid()) {
|
||||
bool valid(false);
|
||||
@@ -892,12 +927,11 @@ bool XineEngine::MakeNewStream() {
|
||||
xine_config_update_entry(xine_, &entry);
|
||||
}
|
||||
}
|
||||
current_device_ = device_;
|
||||
|
||||
audioport_ = xine_open_audio_driver(xine_, (output_.isEmpty() || output_ == kAutoOutput ? nullptr : output_.toUtf8().constData()), nullptr);
|
||||
if (!audioport_) {
|
||||
emit Error("Xine was unable to initialize any audio drivers.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool XineEngine::CreateStream() {
|
||||
|
||||
stream_ = xine_stream_new(xine_, audioport_, nullptr);
|
||||
if (!stream_) {
|
||||
@@ -908,7 +942,6 @@ bool XineEngine::MakeNewStream() {
|
||||
}
|
||||
|
||||
if (eventqueue_) xine_event_dispose_queue(eventqueue_);
|
||||
|
||||
eventqueue_ = xine_event_new_queue(stream_);
|
||||
xine_event_create_listener_thread(eventqueue_, &XineEngine::XineEventListener, (void*)this);
|
||||
|
||||
@@ -923,7 +956,7 @@ bool XineEngine::MakeNewStream() {
|
||||
if (xine_check_version(1, 1, 1) && !(fade_length_ > 0)) {
|
||||
// Enable gapless playback
|
||||
qLog(Debug) << "gapless playback enabled.";
|
||||
// xine_set_param(stream_, XINE_PARAM_EARLY_FINISHED_EVENT, 1);
|
||||
xine_set_param(stream_, XINE_PARAM_EARLY_FINISHED_EVENT, 1);
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
@@ -931,7 +964,7 @@ bool XineEngine::MakeNewStream() {
|
||||
|
||||
bool XineEngine::EnsureStream() {
|
||||
|
||||
if (!stream_) return MakeNewStream();
|
||||
if (!stream_) return CreateStream();
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
@@ -65,9 +65,8 @@ private:
|
||||
|
||||
class XineEngine : public Engine::Base {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
public:
|
||||
XineEngine(TaskManager *task_manager);
|
||||
~XineEngine();
|
||||
|
||||
@@ -86,38 +85,21 @@ public:
|
||||
|
||||
const Engine::Scope& scope(int chunk_length);
|
||||
|
||||
QString DefaultOutput() { return "auto"; }
|
||||
OutputDetailsList GetOutputsList() const;
|
||||
bool CustomDeviceSupport(const QString &name);
|
||||
bool ValidOutput(const QString &output);
|
||||
QString DefaultOutput() { return "auto"; }
|
||||
bool CustomDeviceSupport(const QString &output);
|
||||
|
||||
void ReloadSettings();
|
||||
|
||||
void SetEnvironment();
|
||||
|
||||
uint length() const;
|
||||
uint position() const;
|
||||
|
||||
bool CanDecode(const QUrl &);
|
||||
|
||||
bool MetaDataForUrl(const QUrl &url, Engine::SimpleMetaBundle &b);
|
||||
bool GetAudioCDContents(const QString &device, QList<QUrl> &urls);
|
||||
bool FlushBuffer();
|
||||
bool CreateStream();
|
||||
|
||||
void SetEqualizerEnabled(bool enabled);
|
||||
void SetEqualizerParameters(int preamp, const QList<int>&);
|
||||
|
||||
|
||||
void FadeOut(uint fadeLength, bool* terminate, bool exiting = false);
|
||||
|
||||
static void XineEventListener(void*, const xine_event_t*);
|
||||
bool event(QEvent*);
|
||||
|
||||
Engine::SimpleMetaBundle fetchMetaData() const;
|
||||
|
||||
bool MakeNewStream();
|
||||
bool EnsureStream();
|
||||
|
||||
void DetermineAndShowErrorMessage(); //call after failure to load/play
|
||||
|
||||
// Simple accessors
|
||||
|
||||
xine_stream_t *stream() { return stream_; }
|
||||
@@ -125,10 +107,12 @@ public:
|
||||
bool stop_fader() { return stop_fader_; }
|
||||
void set_stop_fader(bool stop_fader) { stop_fader_ = stop_fader; }
|
||||
|
||||
private:
|
||||
|
||||
private:
|
||||
static const char *kAutoOutput;
|
||||
|
||||
QString current_output_;
|
||||
QVariant current_device_;
|
||||
|
||||
xine_t *xine_;
|
||||
xine_stream_t *stream_;
|
||||
xine_audio_port_t *audioport_;
|
||||
@@ -160,6 +144,26 @@ private:
|
||||
|
||||
mutable Engine::SimpleMetaBundle current_bundle_;
|
||||
|
||||
void SetEnvironment();
|
||||
|
||||
void Cleanup();
|
||||
bool EnsureStream();
|
||||
void SetDevice();
|
||||
|
||||
uint length() const;
|
||||
uint position() const;
|
||||
|
||||
bool MetaDataForUrl(const QUrl &url, Engine::SimpleMetaBundle &b);
|
||||
bool GetAudioCDContents(const QString &device, QList<QUrl> &urls);
|
||||
bool FlushBuffer();
|
||||
|
||||
static void XineEventListener(void*, const xine_event_t*);
|
||||
bool event(QEvent*);
|
||||
|
||||
Engine::SimpleMetaBundle fetchMetaData() const;
|
||||
|
||||
void DetermineAndShowErrorMessage(); //call after failure to load/play
|
||||
|
||||
PluginDetailsList GetPluginList() const;
|
||||
|
||||
private slots:
|
||||
|
||||
@@ -38,7 +38,7 @@ XineFader::XineFader(XineEngine *engine, xine_t *xine, xine_stream_t *stream, xi
|
||||
paused_(false),
|
||||
terminated_(false) {
|
||||
|
||||
if (engine->MakeNewStream()) {
|
||||
if (engine->CreateStream()) {
|
||||
increase_ = stream_;
|
||||
xine_set_param(increase_, XINE_PARAM_AUDIO_AMP_LEVEL, 0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user