source: trunk/src/3rdparty/phonon/ds9/mediaobject.h

Last change on this file was 561, checked in by Dmitry A. Kuminov, 16 years ago

trunk: Merged in qt 4.6.1 sources.

File size: 9.2 KB
Line 
1/* This file is part of the KDE project.
2
3Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4
5This library is free software: you can redistribute it and/or modify
6it under the terms of the GNU Lesser General Public License as published by
7the Free Software Foundation, either version 2.1 or 3 of the License.
8
9This library is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU Lesser General Public License for more details.
13
14You should have received a copy of the GNU Lesser General Public License
15along 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
34QT_BEGIN_NAMESPACE
35
36namespace 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
311QT_END_NAMESPACE
312
313#endif // PHONON_MEDIAOBJECT_H
Note: See TracBrowser for help on using the repository browser.