diff -r 000000000000 -r 1918ee327afb src/3rdparty/phonon/ds9/mediaobject.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/3rdparty/phonon/ds9/mediaobject.h Mon Jan 11 14:00:40 2010 +0000 @@ -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 . +*/ + +#ifndef PHONON_MEDIAOBJECT_H +#define PHONON_MEDIAOBJECT_H + +#include +#include + +#include +#include +#include +#include +#include +#include + +#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(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 = QList()); + + 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 + { + None, + Render, + Seek, + ChangeState, + ReplaceGraph //just updates recalls WaitForMultipleObject + }; + + struct Work + { + Work() : task(None), id(0), time(0) { } + Task task; + quint16 id; + Graph graph; + Graph oldGraph; + Filter filter; + QString url; + union + { + qint64 time; + OAFilterState state; + }; + QList decoders; //for the state change requests + }; + void handleTask(); + + Work m_currentWork; + QQueue m_queue; + bool m_finished; + quint16 m_currentWorkId; + QWinWaitCondition m_waitCondition; + QMutex m_mutex; // mutex for the m_queue, m_finished and m_currentWorkId + + //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 ¶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); + 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 m_videoWidgets; + QList 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 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 &titles); + qint64 titleAbsolutePosition(int title) const; +#endif //QT_NO_PHONON_MEDIACONTROLLER + qint64 m_targetTick; + + WorkerThread m_thread; + }; + } +} + +QT_END_NAMESPACE + +#endif // PHONON_MEDIAOBJECT_H