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
30QT_BEGIN_HEADER
31QT_BEGIN_NAMESPACE
32
33class QByteArray;
34
35#ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM
36
37namespace Phonon
38{
39class MediaObject;
40class 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 */
103class 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
224QT_END_NAMESPACE
225QT_END_HEADER
226
227#endif // PHONON_ABSTRACTMEDIASTREAM_H
228