1
/*  This file is part of the KDE project
2
    Copyright (C) 2007 Matthias Kretz <kretz@kde.org>
3
4
    This library is free software; you can redistribute it and/or
5
    modify it under the terms of the GNU Lesser General Public
6
    License as published by the Free Software Foundation; either
7
    version 2.1 of the License, or (at your option) version 3, or any
8
    later version accepted by the membership of KDE e.V. (or its
9
    successor approved by the membership of KDE e.V.), Nokia Corporation 
10
    (or its successors, if any) and the KDE Free Qt Foundation, which shall
11
    act as a proxy defined in Section 6 of version 3 of the license.
12
13
    This library is distributed in the hope that it will be useful,
14
    but WITHOUT ANY WARRANTY; without even the implied warranty of
15
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
    Lesser General Public License for more details.
17
18
    You should have received a copy of the GNU Lesser General Public 
19
    License along with this library.  If not, see <http://www.gnu.org/licenses/>.
20
21
*/
22
23
#ifndef PHONON_ABSTRACTMEDIASTREAM_H
24
#define PHONON_ABSTRACTMEDIASTREAM_H
25
26
#include "phonon_export.h"
27
#include "phononnamespace.h"
28
#include <QtCore/QObject>
29
30
QT_BEGIN_HEADER
31
QT_BEGIN_NAMESPACE
32
33
class QByteArray;
34
35
#ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM
36
37
namespace Phonon
38
{
39
class MediaObject;
40
class AbstractMediaStreamPrivate;
41
42
/** \class AbstractMediaStream abstractmediastream.h Phonon/AbstractMediaStream
43
 * \brief Base class for custom media data streams.
44
 *
45
 * Implement this class to provide a custom data stream to the backend. The class supports both, the
46
 * push and the pull model.
47
 *
48
 * Push:
49
 * \code
50
 * PushStream::PushStream(QObject *parent)
51
 *   : AbstractMediaStream(parent), m_timer(new QTimer(this))
52
 * {
53
 *   setStreamSize(getMediaStreamSize());
54
 *
55
 *   connect(m_timer, SIGNAL(timeout()), SLOT(moreData()));
56
 *   m_timer->setInterval(0);
57
 * }
58
 *
59
 * void PushStream::moreData()
60
 * {
61
 *   const QByteArray data = getMediaData();
62
 *   if (data.isEmpty()) {
63
 *     endOfData();
64
 *   } else {
65
 *     writeData(data);
66
 *   }
67
 * }
68
 *
69
 * void PushStream::needData()
70
 * {
71
 *   m_timer->start();
72
 *   moreData();
73
 * }
74
 *
75
 * void PushStream::enoughData()
76
 * {
77
 *   m_timer->stop();
78
 * }
79
 * \endcode
80
 *
81
 * Pull:
82
 * \code
83
 * PullStream::PullStream(QObject *parent)
84
 *   : AbstractMediaStream(parent)
85
 * {
86
 *   setStreamSize(getMediaStreamSize());
87
 * }
88
 *
89
 * void PullStream::needData()
90
 * {
91
 *   const QByteArray data = getMediaData();
92
 *   if (data.isEmpty()) {
93
 *     endOfData();
94
 *   } else {
95
 *     writeData(data);
96
 *   }
97
 * }
98
 * \endcode
99
 *
100
 * \ingroup Playback
101
 * \author Matthias Kretz <kretz@kde.org>
102
 */
103
class PHONON_EXPORT AbstractMediaStream : public QObject
104
{
105
    Q_OBJECT
106
    Q_DECLARE_PRIVATE(AbstractMediaStream)
107
    friend class MediaObject;
108
    friend class MediaObjectPrivate;
109
    friend class StreamInterface;
110
    public:
111
        virtual ~AbstractMediaStream();
112
113
    protected:
114
        /**
115
         * Constructs an AbstractMediaStream object with a \p parent.
116
         */
117
        explicit AbstractMediaStream(QObject *parent = 0);
118
119
        /**
120
         * Returns the stream size that was set with \ref setStreamSize.
121
         *
122
         * A negative value means that the length of the stream cannot be known.
123
         *
124
         * Defaults to \c 0.
125
         */
126
        qint64 streamSize() const;
127
128
        /**
129
         * Sets the size of the stream in number of bytes.
130
         *
131
         * A negative value means that the length of the stream cannot be known.
132
         *
133
         * Defaults to 0.
134
         *
135
         * This function has to be called. A backend will not call \ref needData() until the
136
         * stream size is set.
137
         */
138
        void setStreamSize(qint64);
139
140
        /**
141
         * Returns whether your data stream is set as seekable.
142
         *
143
         * Defaults to \c false.
144
         */
145
        bool streamSeekable() const;
146
147
        /**
148
         * Sets whether your data stream is seekable.
149
         *
150
         * Defaults to \c false.
151
         *
152
         * If you set this to \c true you have to implement the \ref seekStream function.
153
         */
154
        void setStreamSeekable(bool);
155
156
        /**
157
         * Sends the media \p data to the backend for decoding.
158
         *
159
         * \warning Don't call this function before the first needData() is emitted.
160
         */
161
        void writeData(const QByteArray &data);
162
163
        /**
164
         * Tells the backend that the media data stream is at its end.
165
         *
166
         * \warning Don't call this function before the first needData() is emitted.
167
         */
168
        void endOfData();
169
170
        /**
171
         * If an I/O error occurs you should call this function to make MediaObject go into
172
         * ErrorState.
173
         *
174
         * \see MediaObject::errorType()
175
         * \see MediaObject::errorString()
176
         */
177
        void error(Phonon::ErrorType errorType, const QString &errorString);
178
179
        /**
180
         * Reimplement this function to reset the stream. Subsequent calls to writeData should start
181
         * from the first position of the data unless a seek is requested.
182
         *
183
         * The function is necessary for the case where a non-seekable MediaStream is
184
         * played more than once. For a seekable stream the implementation can simply call
185
         * \code
186
         * seekStream(0);
187
         * \endcode.
188
         */
189
        virtual void reset() = 0;
190
191
        /**
192
         * Reimplement this function to be notified when the backend needs data.
193
         *
194
         * When this function is called you should try to call writeData or endOfData before
195
         * returning.
196
         */
197
        virtual void needData() = 0;
198
199
        /**
200
         * Reimplement this function to be notified when the backend has enough data and your stream
201
         * object may take a break. This method is important for pushing data to the backend in
202
         * order to not fill the backend buffer unnecessarily.
203
         */
204
        virtual void enoughData();
205
206
        /**
207
         * Reimplement this function if your stream is seekable.
208
         *
209
         * When this function is called the next call to writeData has to be at the requested \p
210
         * offset.
211
         *
212
         * \warning Do not call the parent implementation.
213
         */
214
        virtual void seekStream(qint64 offset);
215
216
        AbstractMediaStream(AbstractMediaStreamPrivate &dd, QObject *parent);
217
        QScopedPointer<AbstractMediaStreamPrivate> d_ptr;
218
};
219
220
} // namespace Phonon
221
222
#endif //QT_NO_PHONON_ABSTRACTMEDIASTREAM
223
224
QT_END_NAMESPACE
225
QT_END_HEADER
226
227
#endif // PHONON_ABSTRACTMEDIASTREAM_H