src/3rdparty/phonon/ds9/mediaobject.h
changeset 0 1918ee327afb
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /*  This file is part of the KDE project.
       
     2 
       
     3 Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 
       
     5 This library is free software: you can redistribute it and/or modify
       
     6 it under the terms of the GNU Lesser General Public License as published by
       
     7 the Free Software Foundation, either version 2.1 or 3 of the License.
       
     8 
       
     9 This library is distributed in the hope that it will be useful,
       
    10 but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    12 GNU Lesser General Public License for more details.
       
    13 
       
    14 You should have received a copy of the GNU Lesser General Public License
       
    15 along with this library.  If not, see <http://www.gnu.org/licenses/>.
       
    16 */
       
    17 
       
    18 #ifndef PHONON_MEDIAOBJECT_H
       
    19 #define PHONON_MEDIAOBJECT_H
       
    20 
       
    21 #include <phonon/mediaobjectinterface.h>
       
    22 #include <phonon/addoninterface.h>
       
    23 
       
    24 #include <QtCore/QHash>
       
    25 #include <QtCore/QObject>
       
    26 #include <QtCore/QQueue>
       
    27 #include <QtCore/QBasicTimer>
       
    28 #include <QtCore/QMutex>
       
    29 #include <QtCore/QThread>
       
    30 
       
    31 #include "backendnode.h"
       
    32 #include "mediagraph.h"
       
    33 
       
    34 QT_BEGIN_NAMESPACE
       
    35 
       
    36 namespace Phonon
       
    37 {
       
    38     class MediaSource;
       
    39 
       
    40     namespace DS9
       
    41     {
       
    42         class VideoWidget;
       
    43         class AudioOutput;
       
    44 
       
    45         class QWinWaitCondition
       
    46         {
       
    47         public:
       
    48             QWinWaitCondition() : m_handle(::CreateEvent(0,0,0,0))
       
    49             {
       
    50             }
       
    51 
       
    52             ~QWinWaitCondition()
       
    53             {
       
    54                 ::CloseHandle(m_handle);
       
    55             }
       
    56 
       
    57             void reset()
       
    58             {
       
    59                 //will block
       
    60                 ::ResetEvent(m_handle);
       
    61             }
       
    62 
       
    63             void set()
       
    64             {
       
    65                 //will unblock
       
    66                 ::SetEvent(m_handle);
       
    67             }
       
    68 
       
    69             operator HANDLE()
       
    70             {
       
    71                 return m_handle;
       
    72             }
       
    73 
       
    74             operator HEVENT()
       
    75             {
       
    76                 return reinterpret_cast<HEVENT>(m_handle);
       
    77             }
       
    78 
       
    79 
       
    80         private:
       
    81             HANDLE m_handle;
       
    82         };
       
    83 
       
    84         class WorkerThread : public QThread
       
    85         {
       
    86             Q_OBJECT
       
    87         public:
       
    88             WorkerThread();
       
    89             ~WorkerThread();
       
    90 
       
    91             virtual void run();
       
    92 
       
    93             //wants to know as soon as the state is set
       
    94             void addStateChangeRequest(Graph graph, OAFilterState, QList<Filter> = QList<Filter>());
       
    95 
       
    96             quint16 addSeekRequest(Graph graph, qint64 time);
       
    97             quint16 addUrlToRender(const QString &url);
       
    98             quint16 addFilterToRender(const Filter &filter);
       
    99 
       
   100             void replaceGraphForEventManagement(Graph newGraph, Graph oldGraph);
       
   101 
       
   102     		void abortCurrentRender(qint16 renderId);
       
   103 
       
   104             //tells the thread to stop processing
       
   105             void signalStop();
       
   106 
       
   107         Q_SIGNALS:
       
   108             void asyncRenderFinished(quint16, HRESULT, Graph);
       
   109             void asyncSeekingFinished(quint16, qint64);
       
   110             void stateReady(Graph, Phonon::State);
       
   111             void eventReady(Graph, long eventCode, long param1);
       
   112 
       
   113         private:
       
   114 
       
   115             enum Task
       
   116             {
       
   117                 None,
       
   118                 Render,
       
   119                 Seek,
       
   120                 ChangeState,
       
   121                 ReplaceGraph //just updates recalls WaitForMultipleObject
       
   122             };
       
   123 
       
   124             struct Work
       
   125             {
       
   126                 Work() : task(None), id(0), time(0) { }
       
   127                 Task task;
       
   128                 quint16 id;
       
   129                 Graph graph;
       
   130                 Graph oldGraph;
       
   131                 Filter filter;
       
   132                 QString url;
       
   133                 union
       
   134                 {
       
   135                     qint64 time;
       
   136                     OAFilterState state;
       
   137                 };
       
   138                 QList<Filter> decoders; //for the state change requests
       
   139             };
       
   140             void handleTask();
       
   141 
       
   142             Work m_currentWork;
       
   143             QQueue<Work> m_queue;
       
   144             bool m_finished;
       
   145             quint16 m_currentWorkId;
       
   146             QWinWaitCondition m_waitCondition;
       
   147             QMutex m_mutex; // mutex for the m_queue, m_finished and m_currentWorkId
       
   148 
       
   149             //this is for WaitForMultipleObjects
       
   150             struct
       
   151             {
       
   152                 Graph graph;
       
   153                 HANDLE handle;
       
   154             } m_graphHandle[FILTER_COUNT];
       
   155         };
       
   156 
       
   157 
       
   158         class MediaObject : public BackendNode, public Phonon::MediaObjectInterface
       
   159 #ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM
       
   160             , public Phonon::AddonInterface
       
   161 #endif //QT_NO_PHONON_ABSTRACTMEDIASTREAM
       
   162         {
       
   163             friend class Stream;
       
   164             Q_OBJECT
       
   165                 Q_INTERFACES(Phonon::MediaObjectInterface 
       
   166 #ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM
       
   167                     Phonon::AddonInterface
       
   168 #endif //QT_NO_PHONON_ABSTRACTMEDIASTREAM
       
   169                     )
       
   170         public:
       
   171             MediaObject(QObject *parent);
       
   172             ~MediaObject();
       
   173             Phonon::State state() const;
       
   174             bool hasVideo() const;
       
   175             bool isSeekable() const;
       
   176             qint64 currentTime() const;
       
   177             qint32 tickInterval() const;
       
   178 
       
   179             void setTickInterval(qint32 newTickInterval);
       
   180             void play();
       
   181             void pause();
       
   182             void stop();
       
   183             void ensureStopped();
       
   184             void seek(qint64 time);
       
   185 
       
   186             QString errorString() const;
       
   187             Phonon::ErrorType errorType() const;
       
   188 
       
   189 #ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM
       
   190             bool hasInterface(Interface) const;
       
   191             QVariant interfaceCall(Interface iface, int command, const QList<QVariant> &params);
       
   192 #endif //QT_NO_PHONON_ABSTRACTMEDIASTREAM
       
   193 
       
   194             qint64 totalTime() const;
       
   195             qint32 prefinishMark() const;
       
   196             void setPrefinishMark(qint32 newPrefinishMark);
       
   197 
       
   198             qint32 transitionTime() const;
       
   199             void setTransitionTime(qint32);
       
   200 
       
   201             qint64 remainingTime() const;
       
   202 
       
   203             MediaSource source() const;
       
   204             void setSource(const MediaSource &source);
       
   205             void setNextSource(const MediaSource &source);
       
   206 
       
   207 
       
   208             //COM error management
       
   209             bool catchComError(HRESULT hr);
       
   210 
       
   211             void grabNode(BackendNode *node);
       
   212             bool connectNodes(BackendNode *source, BackendNode *sink);
       
   213             bool disconnectNodes(BackendNode *source, BackendNode *sink);
       
   214 
       
   215             void switchFilters(int index, Filter oldFilter, Filter newFilter);
       
   216 
       
   217             WorkerThread *workerThread();
       
   218             void loadingFinished(MediaGraph *mg);
       
   219             void seekingFinished(MediaGraph *mg);
       
   220             MediaGraph *currentGraph() const;
       
   221 
       
   222             //this is used by the backend only
       
   223             Phonon::State transactionState;
       
   224 
       
   225          private Q_SLOTS:
       
   226             void switchToNextSource();
       
   227             void slotStateReady(Graph, Phonon::State);
       
   228             void handleEvents(Graph, long eventCode, long param1);
       
   229             void finishLoading(quint16 workId, HRESULT hr, Graph);
       
   230             void finishSeeking(quint16 workId, qint64 time);
       
   231 
       
   232          Q_SIGNALS:
       
   233             void stateChanged(Phonon::State newstate, Phonon::State oldstate);
       
   234             void tick(qint64 time);
       
   235             void metaDataChanged(QMultiMap<QString, QString>);
       
   236             void seekableChanged(bool);
       
   237             void hasVideoChanged(bool);
       
   238             void bufferStatus(int);
       
   239 
       
   240             // AddonInterface:
       
   241             void titleChanged(int);
       
   242             void availableTitlesChanged(int);
       
   243             void chapterChanged(int);
       
   244             void availableChaptersChanged(int);
       
   245             void angleChanged(int);
       
   246             void availableAnglesChanged(int);
       
   247 
       
   248             void finished();
       
   249             void prefinishMarkReached(qint32);
       
   250             void aboutToFinish();
       
   251             void totalTimeChanged(qint64 length) const;
       
   252             void currentSourceChanged(const MediaSource &);
       
   253 
       
   254         protected:
       
   255             void setState(Phonon::State);
       
   256             void timerEvent(QTimerEvent *e);
       
   257 
       
   258         private:
       
   259 #ifndef QT_NO_PHONON_VIDEO
       
   260             void updateVideoGeometry();
       
   261 #endif // QT_NO_PHONON_VIDEO
       
   262             void handleComplete(IGraphBuilder *graph);
       
   263             MediaGraph *nextGraph() const;
       
   264 
       
   265             void updateTargetTick();
       
   266             void updateStopPosition();
       
   267 
       
   268             mutable QString m_errorString;
       
   269             mutable Phonon::ErrorType m_errorType;
       
   270 
       
   271             Phonon::State m_state;
       
   272             Phonon::State m_nextState;
       
   273             qint32 m_transitionTime;
       
   274 
       
   275             qint32 m_prefinishMark;
       
   276 
       
   277             QBasicTimer m_tickTimer;
       
   278             qint32 m_tickInterval;
       
   279 
       
   280             //the graph(s)
       
   281             MediaGraph* m_graphs[FILTER_COUNT];
       
   282 
       
   283             //...the videowidgets in the graph
       
   284             QList<VideoWidget*> m_videoWidgets;
       
   285             QList<AudioOutput*> m_audioOutputs;
       
   286 
       
   287             bool m_buffering:1;
       
   288             bool m_oldHasVideo:1;
       
   289             bool m_prefinishMarkSent:1;
       
   290             bool m_aboutToFinishSent:1;
       
   291             bool m_nextSourceReadyToStart:1;
       
   292 
       
   293             //for TitleInterface (and commands)
       
   294 #ifndef QT_NO_PHONON_MEDIACONTROLLER
       
   295             bool m_autoplayTitles:1;
       
   296             QList<qint64> m_titles;
       
   297             int m_currentTitle;
       
   298             int _iface_availableTitles() const;
       
   299             int _iface_currentTitle() const;
       
   300             void _iface_setCurrentTitle(int title, bool bseek = true);
       
   301             void setTitles(const QList<qint64> &titles);
       
   302             qint64 titleAbsolutePosition(int title) const;
       
   303 #endif //QT_NO_PHONON_MEDIACONTROLLER
       
   304             qint64 m_targetTick;
       
   305 
       
   306             WorkerThread m_thread;
       
   307         };
       
   308     }
       
   309 }
       
   310 
       
   311 QT_END_NAMESPACE
       
   312 
       
   313 #endif // PHONON_MEDIAOBJECT_H