File indexing completed on 2024-04-28 12:31:47

0001 /*  This file is part of the KDE project
0002     Copyright (C) 2007 Matthias Kretz <kretz@kde.org>
0003 
0004     This library is free software; you can redistribute it and/or
0005     modify it under the terms of the GNU Lesser General Public
0006     License as published by the Free Software Foundation; either
0007     version 2.1 of the License, or (at your option) version 3, or any
0008     later version accepted by the membership of KDE e.V. (or its
0009     successor approved by the membership of KDE e.V.), Nokia Corporation
0010     (or its successors, if any) and the KDE Free Qt Foundation, which shall
0011     act as a proxy defined in Section 6 of version 3 of the license.
0012 
0013     This library is distributed in the hope that it will be useful,
0014     but WITHOUT ANY WARRANTY; without even the implied warranty of
0015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0016     Lesser General Public License for more details.
0017 
0018     You should have received a copy of the GNU Lesser General Public
0019     License along with this library.  If not, see <http://www.gnu.org/licenses/>.
0020 
0021 */
0022 
0023 #ifndef PHONON_ABSTRACTMEDIASTREAM_H
0024 #define PHONON_ABSTRACTMEDIASTREAM_H
0025 
0026 #include "phonon_export.h"
0027 #include "phononnamespace.h"
0028 #include <QObject>
0029 
0030 
0031 class QByteArray;
0032 
0033 #ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM
0034 
0035 namespace Phonon
0036 {
0037 class MediaObject;
0038 class AbstractMediaStreamPrivate;
0039 
0040 /** \class AbstractMediaStream abstractmediastream.h phonon/AbstractMediaStream
0041  * \brief Base class for custom media data streams.
0042  *
0043  * Implement this class to provide a custom data stream to the backend. The class supports both, the
0044  * push and the pull model.
0045  *
0046  * Push:
0047  * \code
0048  * PushStream::PushStream(QObject *parent)
0049  *   : AbstractMediaStream(parent), m_timer(new QTimer(this))
0050  * {
0051  *   setStreamSize(getMediaStreamSize());
0052  *
0053  *   connect(m_timer, SIGNAL(timeout()), SLOT(moreData()));
0054  *   m_timer->setInterval(0);
0055  * }
0056  *
0057  * void PushStream::moreData()
0058  * {
0059  *   const QByteArray data = getMediaData();
0060  *   if (data.isEmpty()) {
0061  *     endOfData();
0062  *   } else {
0063  *     writeData(data);
0064  *   }
0065  * }
0066  *
0067  * void PushStream::needData()
0068  * {
0069  *   m_timer->start();
0070  *   moreData();
0071  * }
0072  *
0073  * void PushStream::enoughData()
0074  * {
0075  *   m_timer->stop();
0076  * }
0077  * \endcode
0078  *
0079  * Pull:
0080  * \code
0081  * PullStream::PullStream(QObject *parent)
0082  *   : AbstractMediaStream(parent)
0083  * {
0084  *   setStreamSize(getMediaStreamSize());
0085  * }
0086  *
0087  * void PullStream::needData()
0088  * {
0089  *   const QByteArray data = getMediaData();
0090  *   if (data.isEmpty()) {
0091  *     endOfData();
0092  *   } else {
0093  *     writeData(data);
0094  *   }
0095  * }
0096  * \endcode
0097  *
0098  * \ingroup Playback
0099  * \author Matthias Kretz <kretz@kde.org>
0100  */
0101 class PHONON_EXPORT AbstractMediaStream : public QObject
0102 {
0103     Q_OBJECT
0104     Q_DECLARE_PRIVATE(AbstractMediaStream)
0105     friend class MediaObject;
0106     friend class MediaObjectPrivate;
0107     friend class StreamInterface;
0108     public:
0109         ~AbstractMediaStream() override;
0110 
0111     protected:
0112         /**
0113          * Constructs an AbstractMediaStream object with a \p parent.
0114          */
0115         explicit AbstractMediaStream(QObject *parent = nullptr);
0116 
0117         /**
0118          * Returns the stream size that was set with \ref setStreamSize.
0119          *
0120          * A negative value means that the length of the stream cannot be known.
0121          *
0122          * Defaults to \c 0.
0123          */
0124         qint64 streamSize() const;
0125 
0126         /**
0127          * Sets the size of the stream in number of bytes.
0128          *
0129          * A negative value means that the length of the stream cannot be known.
0130          *
0131          * Defaults to 0.
0132          *
0133          * This function has to be called. A backend will not call \ref needData() until the
0134          * stream size is set.
0135          */
0136         void setStreamSize(qint64);
0137 
0138         /**
0139          * Returns whether your data stream is set as seekable.
0140          *
0141          * Defaults to \c false.
0142          */
0143         bool streamSeekable() const;
0144 
0145         /**
0146          * Sets whether your data stream is seekable.
0147          *
0148          * Defaults to \c false.
0149          *
0150          * If you set this to \c true you have to implement the \ref seekStream function.
0151          */
0152         void setStreamSeekable(bool);
0153 
0154         /**
0155          * Sends the media \p data to the backend for decoding.
0156          *
0157          * \warning Don't call this function before the first needData() is emitted.
0158          */
0159         void writeData(const QByteArray &data);
0160 
0161         /**
0162          * Tells the backend that the media data stream is at its end.
0163          *
0164          * \warning Don't call this function before the first needData() is emitted.
0165          */
0166         void endOfData();
0167 
0168         /**
0169          * If an I/O error occurs you should call this function to make MediaObject go into
0170          * ErrorState.
0171          *
0172          * \see MediaObject::errorType()
0173          * \see MediaObject::errorString()
0174          */
0175         void error(Phonon::ErrorType errorType, const QString &errorString);
0176 
0177         /**
0178          * Reimplement this function to reset the stream. Subsequent calls to writeData should start
0179          * from the first position of the data unless a seek is requested.
0180          *
0181          * The function is necessary for the case where a non-seekable MediaStream is
0182          * played more than once. For a seekable stream the implementation can simply call
0183          * \code
0184          * seekStream(0);
0185          * \endcode.
0186          */
0187         Q_INVOKABLE virtual void reset() = 0;
0188 
0189         /**
0190          * Reimplement this function to be notified when the backend needs data.
0191          *
0192          * When this function is called you should try to call writeData or endOfData before
0193          * returning.
0194          */
0195         Q_INVOKABLE virtual void needData() = 0;
0196 
0197         /**
0198          * Reimplement this function to be notified when the backend has enough data and your stream
0199          * object may take a break. This method is important for pushing data to the backend in
0200          * order to not fill the backend buffer unnecessarily.
0201          */
0202         Q_INVOKABLE virtual void enoughData();
0203 
0204         /**
0205          * Reimplement this function if your stream is seekable.
0206          *
0207          * When this function is called the next call to writeData has to be at the requested \p
0208          * offset.
0209          *
0210          * \warning Do not call the parent implementation.
0211          */
0212         Q_INVOKABLE virtual void seekStream(qint64 offset);
0213 
0214         AbstractMediaStream(AbstractMediaStreamPrivate &dd, QObject *parent);
0215         QScopedPointer<AbstractMediaStreamPrivate> d_ptr;
0216 };
0217 
0218 } // namespace Phonon
0219 
0220 #endif //QT_NO_PHONON_ABSTRACTMEDIASTREAM
0221 
0222 
0223 #endif // PHONON_ABSTRACTMEDIASTREAM_H