1
/*  This file is part of the KDE project.
2
3
    Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
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_MEDIAOBJECT_H
19
#define Phonon_GSTREAMER_MEDIAOBJECT_H
20
21
#include "backend.h"
22
#include "common.h"
23
#include "medianode.h"
24
#include <phonon/mediaobjectinterface.h>
25
#include <phonon/addoninterface.h>
26
27
#include <QtCore/QHash>
28
#include <QtCore/QString>
29
#include <QtCore/QVariant>
30
#include <QtCore/QObject>
31
#include <QtCore/QDate>
32
#include <QtCore/QEvent>
33
#include <QtCore/QUrl>
34
#include <gst/gst.h>
35
36
QT_BEGIN_NAMESPACE
37
38
class QTimer;
39
typedef QMultiMap<QString, QString> TagMap;
40
41
namespace Phonon
42
{
43
namespace Gstreamer
44
{
45
46
class VideoWidget;
47
class AudioPath;
48
class VideoPath;
49
class AudioOutput;
50
51
class MediaObject : public QObject, public MediaObjectInterface
52
#ifndef QT_NO_PHONON_MEDIACONTROLLER
53
        , public AddonInterface
54
#endif
55
        , public MediaNode
56
{
57
    friend class Stream;
58
    friend class AudioDataOutput;
59
    Q_OBJECT
60
    Q_INTERFACES(Phonon::MediaObjectInterface
61
#ifndef QT_NO_PHONON_MEDIACONTROLLER
62
                 Phonon::AddonInterface
63
#endif
64
                 Phonon::Gstreamer::MediaNode
65
    )
66
67
public:
68
69
    MediaObject(Backend *backend, QObject *parent);
70
    ~MediaObject();
71
    Phonon::State state() const;
72
73
    bool hasVideo() const;
74
    bool isSeekable() const;
75
76
    qint64 currentTime() const;
77
    qint32 tickInterval() const;
78
79
    void setTickInterval(qint32 newTickInterval);
80
81
    void play();
82
    void pause();
83
    void stop();
84
    void seek(qint64 time);
85
86
    QString errorString() const;
87
    Phonon::ErrorType errorType() const;
88
89
    QUrl url() const;
90
    qint64 totalTime() const;
91
92
    qint32 prefinishMark() const;
93
    void setPrefinishMark(qint32 newPrefinishMark);
94
95
    qint32 transitionTime() const;
96
    void setTransitionTime(qint32);
97
    qint64 remainingTime() const;
98
99
    void setSource(const MediaSource &source);
100
    void setNextSource(const MediaSource &source);
101
    MediaSource source() const;
102
103
    // No additional interfaces currently supported
104
#ifndef QT_NO_PHONON_MEDIACONTROLLER
105
    bool hasInterface(Interface) const;
106
    QVariant interfaceCall(Interface, int, const QList<QVariant> &);
107
#endif
108
    bool isLoading()
109
    {
110
        return m_loading;
111
    }
112
113
    bool audioAvailable()
114
    {
115
        return m_hasAudio;
116
    }
117
118
    bool videoAvailable()
119
    {
120
        return m_hasVideo;
121
    }
122
123
    GstElement *audioGraph()
124
    {
125
        return m_audioGraph;
126
    }
127
128
    GstElement *videoGraph()
129
    {
130
        return m_videoGraph;
131
    }
132
133
    GstElement *pipeline()
134
    {
135
        return m_pipeline;
136
    };
137
138
    gulong capsHandler()
139
    {
140
        return m_capsHandler;
141
    };
142
143
    void connectVideo(GstPad *videoPad);
144
    void connectAudio(GstPad *audioPad);
145
    void handleBusMessage(const Message &msg);
146
    void handleEndOfStream();
147
    void addMissingCodecName(const QString &codec) { m_missingCodecs.append(codec); }
148
    void invalidateGraph();
149
150
    static void cb_newpad (GstElement *decodebin, GstPad *pad, gboolean last, gpointer data);
151
    static void cb_pad_added (GstElement *decodebin, GstPad *pad, gpointer data);
152
    static void cb_unknown_type (GstElement *decodebin, GstPad *pad, GstCaps *caps, gpointer data);
153
    static void cb_no_more_pads (GstElement * decodebin, gpointer data);
154
    void saveState();
155
    void resumeState();
156
157
public Q_SLOTS:
158
    void setState(State);
159
    
160
Q_SIGNALS:
161
    void currentSourceChanged(const MediaSource &newSource);
162
    void stateChanged(Phonon::State newstate, Phonon::State oldstate);
163
    void tick(qint64 time);
164
    void metaDataChanged(QMultiMap<QString, QString>);
165
    void seekableChanged(bool);
166
    void hasVideoChanged(bool);
167
168
    void finished();
169
    void prefinishMarkReached(qint32);
170
    void aboutToFinish();
171
    void totalTimeChanged(qint64 length);
172
    void bufferStatus(int percentFilled);
173
174
    QMultiMap<QString, QString> metaData();
175
    void setMetaData(QMultiMap<QString, QString> newData);
176
177
    // AddonInterface:
178
    void titleChanged(int);
179
    void availableTitlesChanged(int);
180
181
    // Not implemented
182
    void chapterChanged(int);
183
    void availableChaptersChanged(int);
184
    void angleChanged(int);
185
    void availableAnglesChanged(int);
186
187
    void availableSubtitlesChanged();
188
    void availableAudioChannelsChanged();
189
190
protected:
191
    void beginLoad();
192
    void loadingComplete();
193
    void newPadAvailable (GstPad *pad);
194
    void changeState(State);
195
    void setError(const QString &errorString, Phonon::ErrorType error = NormalError);
196
    /*
197
     * @param encodedUrl percent-encoded QString for source compat reasons.  Should change to QUrl
198
     */
199
    bool createPipefromURL(const QUrl &url);
200
    bool createPipefromStream(const MediaSource &);
201
202
private Q_SLOTS:
203
    void noMorePadsAvailable();    
204
    void getStreamInfo();
205
    void emitTick();
206
    void beginPlay();
207
    void setVideoCaps(GstCaps *caps);
208
    void notifyStateChange(Phonon::State newstate, Phonon::State oldstate);
209
protected:
210
    GstElement *audioElement()
211
    {
212
        Q_ASSERT(m_audioPipe);
213
        return m_audioPipe;
214
    }
215
216
    GstElement *videoElement()
217
    {
218
        Q_ASSERT(m_videoPipe);
219
        return m_videoPipe;
220
    }
221
222
private:
223
224
    // GStreamer specific :
225
    void createPipeline();
226
    bool addToPipeline(GstElement *elem);
227
    void setTotalTime(qint64 newTime);
228
    void getStreamsInfo();
229
    bool updateTotalTime();
230
    void updateSeekable();
231
    qint64 getPipelinePos() const;
232
233
    int _iface_availableTitles() const;
234
    int _iface_currentTitle() const;
235
    void _iface_setCurrentTitle(int title);
236
    void setTrack(int title);
237
238
    bool m_resumeState;
239
    State m_oldState;
240
    quint64 m_oldPos;
241
242
    State m_state;
243
    State m_pendingState;
244
    QTimer *m_tickTimer;
245
    qint32 m_tickInterval;
246
247
    MediaSource m_source;
248
    MediaSource m_nextSource;
249
    qint32 m_prefinishMark;
250
    qint32 m_transitionTime;
251
	bool m_isStream;
252
253
    qint64 m_posAtSeek;
254
255
    bool m_prefinishMarkReachedNotEmitted;
256
    bool m_aboutToFinishEmitted;
257
    bool m_loading;
258
    gulong m_capsHandler;
259
260
    GstElement *m_datasource;
261
    GstElement *m_decodebin;
262
263
    GstElement *m_audioPipe;
264
    GstElement *m_videoPipe;
265
266
    qint64 m_totalTime;
267
    int m_bufferPercent;
268
    bool m_hasVideo;
269
    bool m_videoStreamFound;
270
    bool m_hasAudio;
271
    bool m_seekable;
272
    bool m_atEndOfStream;
273
    bool m_atStartOfStream;
274
    Phonon::ErrorType m_error;
275
    QString m_errorString;
276
277
    GstElement *m_pipeline;
278
    GstElement *m_audioGraph;
279
    GstElement *m_videoGraph;
280
    int m_previousTickTime;
281
    bool m_resetNeeded;
282
    QStringList m_missingCodecs;
283
    QMultiMap<QString, QString> m_metaData;
284
    bool m_autoplayTitles;
285
    int m_availableTitles;
286
    int m_currentTitle;
287
    int m_pendingTitle;
288
};
289
}
290
} //namespace Phonon::Gstreamer
291
292
QT_END_NAMESPACE
293
294
#endif // Phonon_GSTREAMER_MEDIAOBJECT_H