1 | /* This file is part of the KDE project. |
2 | |
3 | Copyright (C) 2011 Torrie Fischer <tdfischer@kde.org> |
4 | |
5 | This library is free software: you can redistribute it and/or modify |
6 | it under the terms of the GNU Lesser General Public License as published by |
7 | the Free Software Foundation, either version 2.1 or 3 of the License. |
8 | |
9 | This library is distributed in the hope that it will be useful, |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | GNU Lesser General Public License for more details. |
13 | |
14 | You should have received a copy of the GNU Lesser General Public License |
15 | along with this library. If not, see <http://www.gnu.org/licenses/>. |
16 | */ |
17 | |
18 | #ifndef Phonon_GSTREAMER_PIPELINE_H |
19 | #define Phonon_GSTREAMER_PIPELINE_H |
20 | |
21 | #include "plugininstaller.h" |
22 | #include <gst/gst.h> |
23 | #include <phonon/MediaSource> |
24 | #include <phonon/MediaController> |
25 | #include <QtCore/QMutex> |
26 | |
27 | typedef QMultiMap<QString, QString> TagMap; |
28 | |
29 | namespace Phonon |
30 | { |
31 | namespace Gstreamer |
32 | { |
33 | |
34 | class MediaObject; |
35 | class PluginInstaller; |
36 | class StreamReader; |
37 | |
38 | class Pipeline : public QObject |
39 | { |
40 | Q_OBJECT |
41 | |
42 | public: |
43 | Pipeline(QObject *parent = 0); |
44 | virtual ~Pipeline(); |
45 | GstElement *element() const; |
46 | GstElement *videoGraph() const; |
47 | GstElement *audioGraph() const; |
48 | GstElement *videoElement() const; |
49 | GstElement *audioElement() const; |
50 | GstStateChangeReturn setState(GstState state); |
51 | GstState state() const; |
52 | Phonon::MediaSource currentSource() const; |
53 | void writeToDot(MediaObject *media, const QString &type); |
54 | bool queryDuration(GstFormat *format, gint64 *duration) const; |
55 | qint64 totalDuration() const; |
56 | |
57 | static gboolean cb_eos(GstBus *bus, GstMessage *msg, gpointer data); |
58 | static gboolean cb_warning(GstBus *bus, GstMessage *msg, gpointer data); |
59 | static gboolean cb_duration(GstBus *bus, GstMessage *msg, gpointer data); |
60 | static gboolean cb_buffering(GstBus *bus, GstMessage *msg, gpointer data); |
61 | static gboolean cb_state(GstBus *bus, GstMessage *msg, gpointer data); |
62 | static gboolean cb_element(GstBus *bus, GstMessage *msg, gpointer data); |
63 | static gboolean cb_error(GstBus *bus, GstMessage *msg, gpointer data); |
64 | static gboolean cb_tag(GstBus *bus, GstMessage *msg, gpointer data); |
65 | |
66 | static void cb_aboutToFinish(GstElement *appSrc, gpointer data); |
67 | static void cb_endOfPads(GstElement *playbin, gpointer data); |
68 | |
69 | void setSource(const Phonon::MediaSource &source, bool reset = false); |
70 | |
71 | static void cb_videoChanged(GstElement *playbin, gpointer data); |
72 | static void cb_textTagsChanged(GstElement *playbin, gint stream, gpointer data); |
73 | static void cb_audioTagsChanged(GstElement *playbin, gint stream, gpointer data); |
74 | |
75 | GstElement *audioPipe(); |
76 | GstElement *videoPipe(); |
77 | GstElement *audioGraph(); |
78 | GstElement *videoGraph(); |
79 | |
80 | bool videoIsAvailable() const; |
81 | bool audioIsAvailable() const; |
82 | |
83 | QMultiMap<QString, QString> metaData() const; |
84 | //FIXME: We should be able to specify merging of metadata a la gstreamer's API design |
85 | void setMetaData(const QMultiMap<QString, QString> &newData); |
86 | |
87 | QList<MediaController::NavigationMenu> () const; |
88 | void updateNavigation(); |
89 | |
90 | bool seekToMSec(qint64 time); |
91 | bool isSeekable() const; |
92 | |
93 | Phonon::State phononState() const; |
94 | static void cb_setupSource(GstElement *playbin, GParamSpec *spec, gpointer data); |
95 | |
96 | qint64 position() const; |
97 | QByteArray captureDeviceURI(const MediaSource &source) const; |
98 | |
99 | signals: |
100 | void windowIDNeeded(); |
101 | void eos(); |
102 | void warning(const QString &message); |
103 | void durationChanged(qint64 totalDuration); |
104 | void trackCountChanged(int tracks); |
105 | void buffering(int); |
106 | void stateChanged(GstState oldState, GstState newState); |
107 | void videoAvailabilityChanged(bool); |
108 | void textTagChanged(int stream); |
109 | void audioTagChanged(int stream); |
110 | void errorMessage(const QString &message, Phonon::ErrorType type); |
111 | // Only emitted when metadata changes in the middle of a stream. |
112 | void metaDataChanged(QMultiMap<QString, QString>); |
113 | void mouseOverActive(bool isActive); |
114 | void (QList<MediaController::NavigationMenu>); |
115 | void seekableChanged(bool isSeekable); |
116 | void aboutToFinish(); |
117 | void streamChanged(); |
118 | |
119 | private: |
120 | GstPipeline *m_pipeline; |
121 | int m_bufferPercent; |
122 | |
123 | // Keeps track of whether or not we jump to GST_STATE_PLAYING after plugin installtion is finished. |
124 | // Otherwise, it is possible to jump to another track, play a few seconds, pause, then finish installation |
125 | // and spontaniously start playback without user action. |
126 | bool m_resumeAfterInstall; |
127 | // Determines if we're using an QIODevice stream |
128 | bool m_isStream; |
129 | bool m_isHttpUrl; |
130 | QMultiMap<QString, QString> m_metaData; |
131 | QList<MediaController::NavigationMenu> ; |
132 | Phonon::MediaSource m_currentSource; |
133 | PluginInstaller *m_installer; |
134 | StreamReader *m_reader; |
135 | GstElement *m_audioGraph; |
136 | GstElement *m_videoGraph; |
137 | GstElement *m_audioPipe; |
138 | GstElement *m_videoPipe; |
139 | |
140 | bool m_seeking; |
141 | bool m_resetting; |
142 | qint64 m_posAtReset; |
143 | QMutex m_tagLock; |
144 | |
145 | private Q_SLOTS: |
146 | void pluginInstallFailure(const QString &msg); |
147 | void pluginInstallComplete(); |
148 | void pluginInstallStarted(); |
149 | |
150 | }; |
151 | |
152 | } |
153 | } |
154 | |
155 | #endif // Phonon_GSTREAMER_PIPELINE_H |
156 | |