Clementine-audio-player-Mac.../src/engines/gstengine.h

262 lines
7.5 KiB
C++

/***************************************************************************
* 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
#include <gst/gst.h>
#include <QFuture>
#include <QHash>
#include <QList>
#include <QString>
#include <QStringList>
#include <QTimerEvent>
#include <memory>
#include "bufferconsumer.h"
#include "core/timeconstants.h"
#include "enginebase.h"
class QTimer;
class QTimerEvent;
class Application;
class Console;
class DeviceFinder;
class GstEngineDebug;
class GstEnginePipeline;
class TaskManager;
#ifdef Q_OS_DARWIN
struct _GTlsDatabase;
typedef struct _GTlsDatabase GTlsDatabase;
#endif
/**
* @class GstEngine
* @short GStreamer engine plugin
* @author Mark Kretschmann <markey@web.de>
*/
class GstEngine : public Engine::Base, public BufferConsumer {
Q_OBJECT
public:
GstEngine(Application* app);
~GstEngine();
struct OutputDetails {
QString description;
QString icon_name;
QString gstreamer_plugin_name;
QVariant device_property_value;
};
typedef QList<OutputDetails> OutputDetailsList;
static const int kAutoSampleRate = -1;
static const char* kOutFormatDetect;
static const char* kOutFormatS16LE;
static const char* kOutFormatF32LE;
static const char* kSettingsGroup;
static const char* kSettingFormat;
static const char* kAutoSink;
bool Init();
void EnsureInitialised() { initialising_.waitForFinished(); }
void InitialiseGstreamer();
int AddBackgroundStream(const QUrl& url);
void StopBackgroundStream(int id);
void SetBackgroundStreamVolume(int id, int volume);
qint64 position_nanosec() const;
qint64 length_nanosec() const;
Engine::State state() const;
const Engine::Scope& scope(int chunk_length);
OutputDetailsList GetOutputsList() const;
GstElement* CreateElement(const QString& factoryName, GstElement* bin = 0);
// BufferConsumer
void ConsumeBuffer(GstBuffer* buffer, int pipeline_id);
public slots:
void StartPreloading(const MediaPlaybackRequest& req, bool force_stop_at_end,
qint64 beginning_nanosec, qint64 end_nanosec);
bool Load(const MediaPlaybackRequest&, Engine::TrackChangeFlags change,
bool force_stop_at_end, quint64 beginning_nanosec,
qint64 end_nanosec);
bool Play(quint64 offset_nanosec);
void Stop(bool stop_after = false);
void Pause();
void Unpause();
void Seek(quint64 offset_nanosec);
/** Set whether equalizer is enabled */
void SetEqualizerEnabled(bool);
/** Set equalizer preamp and gains, range -100..100. Gains are 10 values. */
void SetEqualizerParameters(int preamp, const QList<int>& bandGains);
/** Set Stereo balance, range -1.0f..1.0f */
void SetStereoBalance(float value);
void ReloadSettings();
void AddBufferConsumer(BufferConsumer* consumer);
void RemoveBufferConsumer(BufferConsumer* consumer);
#ifdef Q_OS_DARWIN
GTlsDatabase* tls_database() const { return tls_database_; }
#endif
void NewDebugConsole(Console* console);
protected:
void SetVolumeSW(uint percent);
void timerEvent(QTimerEvent*);
private:
// Used for debug purposes only.
friend class GstEngineDebug;
std::shared_ptr<GstEnginePipeline> GetCurrentPipeline() {
return current_pipeline_;
}
private slots:
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);
void AddBufferToScope(GstBuffer* buf, int pipeline_id);
void FadeoutFinished();
void FadeoutPauseFinished();
void SeekNow();
void BackgroundStreamFinished();
void BackgroundStreamPlayDone(QFuture<GstStateChangeReturn>, int);
void PlayDone(QFuture<GstStateChangeReturn> future, const quint64, const int);
void BufferingStarted();
void BufferingProgress(int percent);
void BufferingFinished();
private:
struct PluginDetails {
QString name;
QString description;
};
typedef QList<PluginDetails> PluginDetailsList;
PluginDetailsList GetPluginList(const QString& classname) const;
void StartFadeout();
void StartFadeoutPause();
void StartTimers();
void StopTimers();
std::shared_ptr<GstEnginePipeline> CreatePipeline();
std::shared_ptr<GstEnginePipeline> CreatePipeline(
const MediaPlaybackRequest& req, qint64 end_nanosec);
void UpdateScope(int chunk_length);
int AddBackgroundStream(std::shared_ptr<GstEnginePipeline> pipeline);
bool IsCurrentPipeline(int id);
private:
static const qint64 kTimerIntervalNanosec = 1000 * kNsecPerMsec; // 1s
static const qint64 kPreloadGapNanosec = 2000 * kNsecPerMsec; // 2s
static const qint64 kSeekDelayNanosec = 100 * kNsecPerMsec; // 100msec
static const char* kHypnotoadPipeline;
static const char* kEnterprisePipeline;
TaskManager* task_manager_;
int buffering_task_id_;
QFuture<void> initialising_;
QString sink_;
QVariant device_;
std::shared_ptr<GstEnginePipeline> current_pipeline_;
std::shared_ptr<GstEnginePipeline> fadeout_pipeline_;
std::shared_ptr<GstEnginePipeline> fadeout_pause_pipeline_;
QUrl preloaded_url_;
QList<BufferConsumer*> buffer_consumers_;
GstBuffer* latest_buffer_;
bool equalizer_enabled_;
int equalizer_preamp_;
QList<int> equalizer_gains_;
float stereo_balance_;
bool rg_enabled_;
int rg_mode_;
float rg_preamp_;
bool rg_compression_;
qint64 buffer_duration_nanosec_;
int buffer_min_fill_;
bool mono_playback_;
int sample_rate_;
QString format_;
mutable bool can_decode_success_;
mutable bool can_decode_last_;
// Hack to stop seeks happening too often
QTimer* seek_timer_;
bool waiting_to_seek_;
quint64 seek_pos_;
int timer_id_;
int next_element_id_;
QHash<int, std::shared_ptr<GstEnginePipeline>> background_streams_;
bool is_fading_out_to_pause_;
bool has_faded_out_;
int scope_chunk_;
bool have_new_buffer_;
int scope_chunks_;
QList<DeviceFinder*> device_finders_;
#ifdef Q_OS_DARWIN
GTlsDatabase* tls_database_;
#endif
};
Q_DECLARE_METATYPE(GstEngine::OutputDetails)
#endif /*AMAROK_GSTENGINE_H*/