2010-04-06 18:57:02 +02:00
|
|
|
/***************************************************************************
|
|
|
|
* Copyright (C) 2003-2005 by Mark Kretschmann <markey@web.de> *
|
|
|
|
* Copyright (C) 2005 by Jakub Stachowski <qbast@go2.pl> *
|
|
|
|
* Portions Copyright (C) 2006 Paul Cifarelli <paul@cifarelli.net> *
|
|
|
|
* *
|
|
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
|
|
* it under the terms of the GNU General Public License as published by *
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
|
|
* (at your option) any later version. *
|
|
|
|
* *
|
|
|
|
* This program is distributed in the hope that it will be useful, *
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
|
|
* GNU General Public License for more details. *
|
|
|
|
* *
|
|
|
|
* You should have received a copy of the GNU General Public License *
|
|
|
|
* along with this program; if not, write to the *
|
|
|
|
* Free Software Foundation, Inc., *
|
|
|
|
* 51 Franklin Steet, Fifth Floor, Boston, MA 02111-1307, USA. *
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
#ifndef AMAROK_GSTENGINE_H
|
|
|
|
#define AMAROK_GSTENGINE_H
|
|
|
|
|
2010-06-06 16:06:23 +02:00
|
|
|
#include "bufferconsumer.h"
|
2011-02-14 20:34:37 +01:00
|
|
|
#include "enginebase.h"
|
2011-03-20 20:18:54 +01:00
|
|
|
#include "core/boundfuturewatcher.h"
|
2011-02-14 20:34:37 +01:00
|
|
|
#include "core/timeconstants.h"
|
2010-04-06 18:57:02 +02:00
|
|
|
|
2010-08-27 15:57:39 +02:00
|
|
|
#include <QFuture>
|
2010-06-14 21:15:10 +02:00
|
|
|
#include <QHash>
|
2010-04-06 18:57:02 +02:00
|
|
|
#include <QList>
|
2010-06-14 21:15:10 +02:00
|
|
|
#include <QString>
|
2010-04-06 18:57:02 +02:00
|
|
|
#include <QStringList>
|
2010-06-14 21:15:10 +02:00
|
|
|
#include <QTimerEvent>
|
2010-04-06 18:57:02 +02:00
|
|
|
|
|
|
|
#include <gst/gst.h>
|
2010-04-11 21:47:21 +02:00
|
|
|
#include <boost/shared_ptr.hpp>
|
2010-04-06 18:57:02 +02:00
|
|
|
|
2010-04-22 18:54:09 +02:00
|
|
|
class QTimer;
|
2010-04-06 18:57:02 +02:00
|
|
|
class QTimerEvent;
|
|
|
|
|
2010-04-11 21:47:21 +02:00
|
|
|
class GstEnginePipeline;
|
2012-01-23 15:58:10 +01:00
|
|
|
class TaskManager;
|
2010-04-11 21:47:21 +02:00
|
|
|
|
2010-04-06 18:57:02 +02:00
|
|
|
/**
|
|
|
|
* @class GstEngine
|
|
|
|
* @short GStreamer engine plugin
|
|
|
|
* @author Mark Kretschmann <markey@web.de>
|
|
|
|
*/
|
2010-06-06 16:06:23 +02:00
|
|
|
class GstEngine : public Engine::Base, public BufferConsumer {
|
2010-04-07 00:58:41 +02:00
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
public:
|
2012-01-23 15:58:10 +01:00
|
|
|
GstEngine(TaskManager* task_manager);
|
2010-04-07 00:58:41 +02:00
|
|
|
~GstEngine();
|
|
|
|
|
2010-04-07 15:51:14 +02:00
|
|
|
struct PluginDetails {
|
|
|
|
QString name;
|
|
|
|
QString long_name;
|
|
|
|
QString author;
|
|
|
|
QString description;
|
|
|
|
};
|
|
|
|
typedef QList<PluginDetails> PluginDetailsList;
|
|
|
|
|
|
|
|
static const char* kSettingsGroup;
|
|
|
|
static const char* kAutoSink;
|
|
|
|
|
2010-04-12 01:24:03 +02:00
|
|
|
bool Init();
|
2010-08-28 21:22:58 +02:00
|
|
|
void EnsureInitialised() { initialising_.waitForFinished(); }
|
2011-05-19 18:34:33 +02:00
|
|
|
static void InitialiseGstreamer();
|
2010-04-12 01:24:03 +02:00
|
|
|
|
2010-06-14 21:15:10 +02:00
|
|
|
int AddBackgroundStream(const QUrl& url);
|
|
|
|
void StopBackgroundStream(int id);
|
2010-12-03 14:53:43 +01:00
|
|
|
void SetBackgroundStreamVolume(int id, int volume);
|
2010-06-14 21:15:10 +02:00
|
|
|
|
2011-02-13 19:29:27 +01:00
|
|
|
qint64 position_nanosec() const;
|
|
|
|
qint64 length_nanosec() const;
|
2010-04-07 00:58:41 +02:00
|
|
|
Engine::State state() const;
|
|
|
|
const Engine::Scope& scope();
|
|
|
|
|
2010-04-07 15:51:14 +02:00
|
|
|
PluginDetailsList GetOutputsList() const { return GetPluginList( "Sink/Audio" ); }
|
2010-04-08 22:17:57 +02:00
|
|
|
static bool DoesThisSinkSupportChangingTheOutputDeviceToAUserEditableString(const QString& name);
|
2010-04-07 15:51:14 +02:00
|
|
|
|
2010-08-02 20:13:40 +02:00
|
|
|
GstElement* CreateElement(const QString& factoryName, GstElement* bin = 0);
|
2010-04-11 21:47:21 +02:00
|
|
|
|
2010-06-06 16:06:23 +02:00
|
|
|
// BufferConsumer
|
2011-03-20 22:40:53 +01:00
|
|
|
void ConsumeBuffer(GstBuffer *buffer, int pipeline_id);
|
2010-06-06 16:06:23 +02:00
|
|
|
|
2010-04-07 00:58:41 +02:00
|
|
|
public slots:
|
2011-03-29 00:11:07 +02:00
|
|
|
void StartPreloading(const QUrl& url, bool force_stop_at_end,
|
|
|
|
qint64 beginning_nanosec, qint64 end_nanosec);
|
2011-03-13 19:37:46 +01:00
|
|
|
bool Load(const QUrl&, Engine::TrackChangeFlags change,
|
2011-03-29 00:11:07 +02:00
|
|
|
bool force_stop_at_end,
|
2011-02-13 19:29:27 +01:00
|
|
|
quint64 beginning_nanosec, qint64 end_nanosec);
|
|
|
|
bool Play(quint64 offset_nanosec);
|
2010-04-12 01:24:03 +02:00
|
|
|
void Stop();
|
|
|
|
void Pause();
|
|
|
|
void Unpause();
|
2011-02-13 19:29:27 +01:00
|
|
|
void Seek(quint64 offset_nanosec);
|
2010-04-07 00:58:41 +02:00
|
|
|
|
|
|
|
/** Set whether equalizer is enabled */
|
2010-04-12 01:24:03 +02:00
|
|
|
void SetEqualizerEnabled(bool);
|
2010-04-07 00:58:41 +02:00
|
|
|
|
|
|
|
/** Set equalizer preamp and gains, range -100..100. Gains are 10 values. */
|
2010-04-12 01:24:03 +02:00
|
|
|
void SetEqualizerParameters(int preamp, const QList<int>& bandGains);
|
2010-04-07 00:58:41 +02:00
|
|
|
|
2013-04-27 05:05:42 +02:00
|
|
|
/** Set Stereo balance, range -1.0f..1.0f */
|
|
|
|
void SetStereoBalance(float value);
|
|
|
|
|
2010-04-07 15:51:14 +02:00
|
|
|
void ReloadSettings();
|
|
|
|
|
2010-06-06 16:06:23 +02:00
|
|
|
void AddBufferConsumer(BufferConsumer* consumer);
|
|
|
|
void RemoveBufferConsumer(BufferConsumer* consumer);
|
|
|
|
|
2010-04-07 00:58:41 +02:00
|
|
|
protected:
|
2010-04-12 01:24:03 +02:00
|
|
|
void SetVolumeSW(uint percent);
|
2010-04-07 00:58:41 +02:00
|
|
|
void timerEvent(QTimerEvent*);
|
|
|
|
|
|
|
|
private slots:
|
2011-03-20 22:40:53 +01:00
|
|
|
void EndOfStreamReached(int pipeline_id, bool has_next_track);
|
|
|
|
void HandlePipelineError(int pipeline_id, const QString& message, int domain, int error_code);
|
|
|
|
void NewMetaData(int pipeline_id, const Engine::SimpleMetaBundle& bundle);
|
2010-04-12 02:20:52 +02:00
|
|
|
void ClearScopeBuffers();
|
2011-03-20 22:40:53 +01:00
|
|
|
void AddBufferToScope(GstBuffer* buf, int pipeline_id);
|
2010-04-11 23:40:26 +02:00
|
|
|
void FadeoutFinished();
|
2013-04-22 21:42:04 +02:00
|
|
|
void FadeoutPauseFinished();
|
2010-04-22 18:54:09 +02:00
|
|
|
void SeekNow();
|
2010-06-14 21:15:10 +02:00
|
|
|
void BackgroundStreamFinished();
|
2011-05-04 00:38:24 +02:00
|
|
|
void BackgroundStreamPlayDone();
|
|
|
|
void PlayDone();
|
2010-04-07 00:58:41 +02:00
|
|
|
|
2012-01-23 15:58:10 +01:00
|
|
|
void BufferingStarted();
|
|
|
|
void BufferingProgress(int percent);
|
|
|
|
void BufferingFinished();
|
|
|
|
|
2010-04-07 00:58:41 +02:00
|
|
|
private:
|
2011-03-20 22:40:53 +01:00
|
|
|
typedef QPair<quint64, int> PlayFutureWatcherArg;
|
2011-03-20 20:18:54 +01:00
|
|
|
typedef BoundFutureWatcher<GstStateChangeReturn, PlayFutureWatcherArg> PlayFutureWatcher;
|
|
|
|
|
2010-04-22 15:49:16 +02:00
|
|
|
static void SetEnv(const char* key, const QString& value);
|
2010-04-07 15:51:14 +02:00
|
|
|
PluginDetailsList GetPluginList(const QString& classname) const;
|
2010-04-07 00:58:41 +02:00
|
|
|
|
2010-04-12 01:24:03 +02:00
|
|
|
void StartFadeout();
|
2013-04-22 21:42:04 +02:00
|
|
|
void StartFadeoutPause();
|
2010-04-07 00:58:41 +02:00
|
|
|
|
2010-06-30 22:36:16 +02:00
|
|
|
void StartTimers();
|
|
|
|
void StopTimers();
|
|
|
|
|
2010-07-14 13:16:56 +02:00
|
|
|
boost::shared_ptr<GstEnginePipeline> CreatePipeline();
|
2011-03-06 17:35:47 +01:00
|
|
|
boost::shared_ptr<GstEnginePipeline> CreatePipeline(const QUrl& url, qint64 end_nanosec);
|
2010-04-07 00:58:41 +02:00
|
|
|
|
2010-04-12 01:24:03 +02:00
|
|
|
void UpdateScope();
|
|
|
|
qint64 PruneScope();
|
2010-04-12 01:03:39 +02:00
|
|
|
|
2010-07-14 13:43:23 +02:00
|
|
|
int AddBackgroundStream(boost::shared_ptr<GstEnginePipeline> pipeline);
|
|
|
|
|
2010-12-20 20:00:48 +01:00
|
|
|
static QUrl FixupUrl(const QUrl& url);
|
|
|
|
|
2010-04-12 01:24:03 +02:00
|
|
|
private:
|
2011-02-14 20:34:37 +01:00
|
|
|
static const int kTimerIntervalNanosec = 1000 * kNsecPerMsec; // 1s
|
|
|
|
static const int kPreloadGapNanosec = 1000 * kNsecPerMsec; // 1s
|
|
|
|
static const int kSeekDelayNanosec = 100 * kNsecPerMsec; // 100msec
|
2010-04-07 00:58:41 +02:00
|
|
|
|
2010-07-14 13:16:56 +02:00
|
|
|
static const char* kHypnotoadPipeline;
|
2012-01-10 17:00:17 +01:00
|
|
|
static const char* kEnterprisePipeline;
|
2010-07-14 13:16:56 +02:00
|
|
|
|
2012-01-23 15:58:10 +01:00
|
|
|
TaskManager* task_manager_;
|
|
|
|
int buffering_task_id_;
|
|
|
|
|
2010-08-27 15:57:39 +02:00
|
|
|
QFuture<void> initialising_;
|
|
|
|
|
2010-04-07 15:51:14 +02:00
|
|
|
QString sink_;
|
2010-04-08 22:14:11 +02:00
|
|
|
QString device_;
|
2010-04-07 15:51:14 +02:00
|
|
|
|
2010-04-11 21:47:21 +02:00
|
|
|
boost::shared_ptr<GstEnginePipeline> current_pipeline_;
|
2010-04-11 23:40:26 +02:00
|
|
|
boost::shared_ptr<GstEnginePipeline> fadeout_pipeline_;
|
2013-04-22 21:42:04 +02:00
|
|
|
boost::shared_ptr<GstEnginePipeline> fadeout_pause_pipeline_;
|
2010-04-21 15:55:30 +02:00
|
|
|
QUrl preloaded_url_;
|
2010-04-07 00:58:41 +02:00
|
|
|
|
2010-06-06 16:06:23 +02:00
|
|
|
QList<BufferConsumer*> buffer_consumers_;
|
|
|
|
|
2010-04-07 00:58:41 +02:00
|
|
|
GQueue* delayq_;
|
2010-04-12 01:24:03 +02:00
|
|
|
float current_scope_[kScopeSize];
|
2010-04-07 00:58:41 +02:00
|
|
|
int current_sample_;
|
|
|
|
|
2010-04-12 01:24:03 +02:00
|
|
|
bool equalizer_enabled_;
|
|
|
|
int equalizer_preamp_;
|
|
|
|
QList<int> equalizer_gains_;
|
2013-04-27 05:05:42 +02:00
|
|
|
float stereo_balance_;
|
2010-04-07 00:58:41 +02:00
|
|
|
|
2010-05-23 15:07:15 +02:00
|
|
|
bool rg_enabled_;
|
|
|
|
int rg_mode_;
|
|
|
|
float rg_preamp_;
|
|
|
|
bool rg_compression_;
|
|
|
|
|
2011-02-13 19:29:27 +01:00
|
|
|
qint64 buffer_duration_nanosec_;
|
2010-10-11 17:58:05 +02:00
|
|
|
|
2012-05-20 20:50:25 +02:00
|
|
|
bool mono_playback_;
|
|
|
|
|
2010-04-07 00:58:41 +02:00
|
|
|
mutable bool can_decode_success_;
|
|
|
|
mutable bool can_decode_last_;
|
2010-04-22 18:54:09 +02:00
|
|
|
|
|
|
|
// Hack to stop seeks happening too often
|
|
|
|
QTimer* seek_timer_;
|
|
|
|
bool waiting_to_seek_;
|
2011-02-13 19:29:27 +01:00
|
|
|
quint64 seek_pos_;
|
2010-05-03 16:15:42 +02:00
|
|
|
|
2010-07-02 21:23:08 +02:00
|
|
|
int timer_id_;
|
2010-08-02 20:13:40 +02:00
|
|
|
int next_element_id_;
|
2010-06-14 21:15:10 +02:00
|
|
|
|
|
|
|
QHash<int, boost::shared_ptr<GstEnginePipeline> > background_streams_;
|
2013-04-22 21:42:04 +02:00
|
|
|
|
|
|
|
bool is_fading_out_to_pause_;
|
|
|
|
bool has_faded_out_;
|
2010-04-06 18:57:02 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
#endif /*AMAROK_GSTENGINE_H*/
|