diff options
Diffstat (limited to 'src/3rdparty/phonon/ds9/mediaobject.h')
-rw-r--r-- | src/3rdparty/phonon/ds9/mediaobject.h | 313 |
1 files changed, 313 insertions, 0 deletions
diff --git a/src/3rdparty/phonon/ds9/mediaobject.h b/src/3rdparty/phonon/ds9/mediaobject.h new file mode 100644 index 0000000..2c34ffc --- /dev/null +++ b/src/3rdparty/phonon/ds9/mediaobject.h @@ -0,0 +1,313 @@ +/* This file is part of the KDE project. + +Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + +This library is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 2.1 or 3 of the License. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this library. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef PHONON_MEDIAOBJECT_H +#define PHONON_MEDIAOBJECT_H + +#include <phonon/mediaobjectinterface.h> +#include <phonon/addoninterface.h> + +#include <QtCore/QHash> +#include <QtCore/QObject> +#include <QtCore/QQueue> +#include <QtCore/QBasicTimer> +#include <QtCore/QMutex> +#include <QtCore/QThread> + +#include "backendnode.h" +#include "mediagraph.h" + +QT_BEGIN_NAMESPACE + +namespace Phonon +{ + class MediaSource; + + namespace DS9 + { + class VideoWidget; + class AudioOutput; + + class QWinWaitCondition + { + public: + QWinWaitCondition() : m_handle(::CreateEvent(0,0,0,0)) + { + } + + ~QWinWaitCondition() + { + ::CloseHandle(m_handle); + } + + void reset() + { + //will block + ::ResetEvent(m_handle); + } + + void set() + { + //will unblock + ::SetEvent(m_handle); + } + + operator HANDLE() + { + return m_handle; + } + + operator HEVENT() + { + return reinterpret_cast<HEVENT>(m_handle); + } + + + private: + HANDLE m_handle; + }; + + class WorkerThread : public QThread + { + Q_OBJECT + public: + WorkerThread(); + ~WorkerThread(); + + virtual void run(); + + //wants to know as soon as the state is set + void addStateChangeRequest(Graph graph, OAFilterState, QList<Filter> = QList<Filter>()); + + quint16 addSeekRequest(Graph graph, qint64 time); + quint16 addUrlToRender(const QString &url); + quint16 addFilterToRender(const Filter &filter); + + void replaceGraphForEventManagement(Graph newGraph, Graph oldGraph); + + void abortCurrentRender(qint16 renderId); + + //tells the thread to stop processing + void signalStop(); + + Q_SIGNALS: + void asyncRenderFinished(quint16, HRESULT, Graph); + void asyncSeekingFinished(quint16, qint64); + void stateReady(Graph, Phonon::State); + void eventReady(Graph, long eventCode, long param1); + + private: + + enum Task + { + Render, + Seek, + ChangeState, + ReplaceGraph //just updates recalls WaitForMultipleObject + }; + + struct Work + { + Task task; + quint16 id; + Graph graph; + Graph oldGraph; + Filter filter; + QString url; + union + { + qint64 time; + OAFilterState state; + }; + QList<Filter> decoders; //for the state change requests + }; + Work dequeueWork(); + void handleTask(); + + Graph m_currentRender; + qint16 m_currentRenderId; + QQueue<Work> m_queue; + bool m_finished; + quint16 m_currentWorkId; + QWinWaitCondition m_waitCondition; + QMutex m_mutex; + + //this is for WaitForMultipleObjects + struct + { + Graph graph; + HANDLE handle; + } m_graphHandle[FILTER_COUNT]; + }; + + + class MediaObject : public BackendNode, public Phonon::MediaObjectInterface +#ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM + , public Phonon::AddonInterface +#endif //QT_NO_PHONON_ABSTRACTMEDIASTREAM + { + friend class Stream; + Q_OBJECT + Q_INTERFACES(Phonon::MediaObjectInterface +#ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM + Phonon::AddonInterface +#endif //QT_NO_PHONON_ABSTRACTMEDIASTREAM + ) + public: + MediaObject(QObject *parent); + ~MediaObject(); + Phonon::State state() const; + bool hasVideo() const; + bool isSeekable() const; + qint64 currentTime() const; + qint32 tickInterval() const; + + void setTickInterval(qint32 newTickInterval); + void play(); + void pause(); + void stop(); + void ensureStopped(); + void seek(qint64 time); + + QString errorString() const; + Phonon::ErrorType errorType() const; + +#ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM + bool hasInterface(Interface) const; + QVariant interfaceCall(Interface iface, int command, const QList<QVariant> ¶ms); +#endif //QT_NO_PHONON_ABSTRACTMEDIASTREAM + + qint64 totalTime() const; + qint32 prefinishMark() const; + void setPrefinishMark(qint32 newPrefinishMark); + + qint32 transitionTime() const; + void setTransitionTime(qint32); + + qint64 remainingTime() const; + + MediaSource source() const; + void setSource(const MediaSource &source); + void setNextSource(const MediaSource &source); + + + //COM error management + bool catchComError(HRESULT hr); + + void grabNode(BackendNode *node); + bool connectNodes(BackendNode *source, BackendNode *sink); + bool disconnectNodes(BackendNode *source, BackendNode *sink); + + void switchFilters(int index, Filter oldFilter, Filter newFilter); + + WorkerThread *workerThread(); + void loadingFinished(MediaGraph *mg); + void seekingFinished(MediaGraph *mg); + MediaGraph *currentGraph() const; + + //this is used by the backend only + Phonon::State transactionState; + + private Q_SLOTS: + void switchToNextSource(); + void slotStateReady(Graph, Phonon::State); + void handleEvents(Graph, long eventCode, long param1); + void finishLoading(quint16 workId, HRESULT hr, Graph); + void finishSeeking(quint16 workId, qint64 time); + + Q_SIGNALS: + void stateChanged(Phonon::State newstate, Phonon::State oldstate); + void tick(qint64 time); + void metaDataChanged(QMultiMap<QString, QString>); + void seekableChanged(bool); + void hasVideoChanged(bool); + void bufferStatus(int); + + // AddonInterface: + void titleChanged(int); + void availableTitlesChanged(int); + void chapterChanged(int); + void availableChaptersChanged(int); + void angleChanged(int); + void availableAnglesChanged(int); + + void finished(); + void prefinishMarkReached(qint32); + void aboutToFinish(); + void totalTimeChanged(qint64 length) const; + void currentSourceChanged(const MediaSource &); + + protected: + void setState(Phonon::State); + void timerEvent(QTimerEvent *e); + + private: +#ifndef QT_NO_PHONON_VIDEO + void updateVideoGeometry(); +#endif // QT_NO_PHONON_VIDEO + void handleComplete(IGraphBuilder *graph); + MediaGraph *nextGraph() const; + + void updateTargetTick(); + void updateStopPosition(); + + mutable QString m_errorString; + mutable Phonon::ErrorType m_errorType; + + Phonon::State m_state; + Phonon::State m_nextState; + qint32 m_transitionTime; + + qint32 m_prefinishMark; + + QBasicTimer m_tickTimer; + qint32 m_tickInterval; + + //the graph(s) + MediaGraph* m_graphs[FILTER_COUNT]; + + //...the videowidgets in the graph + QList<VideoWidget*> m_videoWidgets; + QList<AudioOutput*> m_audioOutputs; + + bool m_buffering:1; + bool m_oldHasVideo:1; + bool m_prefinishMarkSent:1; + bool m_aboutToFinishSent:1; + bool m_nextSourceReadyToStart:1; + + //for TitleInterface (and commands) +#ifndef QT_NO_PHONON_MEDIACONTROLLER + bool m_autoplayTitles:1; + QList<qint64> m_titles; + int m_currentTitle; + int _iface_availableTitles() const; + int _iface_currentTitle() const; + void _iface_setCurrentTitle(int title, bool bseek = true); + void setTitles(const QList<qint64> &titles); + qint64 titleAbsolutePosition(int title) const; +#endif //QT_NO_PHONON_MEDIACONTROLLER + qint64 m_targetTick; + + WorkerThread m_thread; + }; + } +} + +QT_END_NAMESPACE + +#endif // PHONON_MEDIAOBJECT_H |