summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/phonon
diff options
context:
space:
mode:
authorThierry Bastian <thierry.bastian@nokia.com>2009-08-21 10:17:29 (GMT)
committerThierry Bastian <thierry.bastian@nokia.com>2009-08-21 14:22:06 (GMT)
commit2fbd7208c273404030b9327dd3e2fbcf6aa4491f (patch)
tree5a53823e9b8eaf8312819763b6fee6977443a116 /src/3rdparty/phonon
parente71eaf8afb2b4fac751c8bcddabefd7f21ab7c45 (diff)
downloadQt-2fbd7208c273404030b9327dd3e2fbcf6aa4491f.zip
Qt-2fbd7208c273404030b9327dd3e2fbcf6aa4491f.tar.gz
Qt-2fbd7208c273404030b9327dd3e2fbcf6aa4491f.tar.bz2
Phonon on Windows: improve performance when loading lots of sources
The lock is made more local.
Diffstat (limited to 'src/3rdparty/phonon')
-rw-r--r--src/3rdparty/phonon/ds9/mediagraph.cpp4
-rw-r--r--src/3rdparty/phonon/ds9/mediaobject.cpp115
-rw-r--r--src/3rdparty/phonon/ds9/mediaobject.h6
3 files changed, 53 insertions, 72 deletions
diff --git a/src/3rdparty/phonon/ds9/mediagraph.cpp b/src/3rdparty/phonon/ds9/mediagraph.cpp
index 7b10176..c0cc321 100644
--- a/src/3rdparty/phonon/ds9/mediagraph.cpp
+++ b/src/3rdparty/phonon/ds9/mediagraph.cpp
@@ -383,7 +383,8 @@ namespace Phonon
#endif
if (info.pGraph) {
info.pGraph->Release();
- return m_graph->RemoveFilter(filter);
+ if (info.pGraph == m_graph)
+ return m_graph->RemoveFilter(filter);
}
//already removed
@@ -681,7 +682,6 @@ namespace Phonon
#ifndef QT_NO_PHONON_MEDIACONTROLLER
} else if (source.discType() == Phonon::Cd) {
m_realSource = Filter(new QAudioCDPlayer);
- m_result = m_graph->AddFilter(m_realSource, 0);
#endif //QT_NO_PHONON_MEDIACONTROLLER
} else {
diff --git a/src/3rdparty/phonon/ds9/mediaobject.cpp b/src/3rdparty/phonon/ds9/mediaobject.cpp
index de2078a..314a7be 100644
--- a/src/3rdparty/phonon/ds9/mediaobject.cpp
+++ b/src/3rdparty/phonon/ds9/mediaobject.cpp
@@ -49,7 +49,7 @@ namespace Phonon
//first the definition of the WorkerThread class
WorkerThread::WorkerThread()
- : QThread(), m_currentRenderId(0), m_finished(false), m_currentWorkId(1)
+ : QThread(), m_finished(false), m_currentWorkId(1)
{
}
@@ -157,6 +157,7 @@ namespace Phonon
//we create a new graph
w.graph = Graph(CLSID_FilterGraph, IID_IGraphBuilder);
w.filter = filter;
+ w.graph->AddFilter(filter, 0);
w.id = m_currentWorkId++;
m_queue.enqueue(w);
m_waitCondition.set();
@@ -176,31 +177,28 @@ namespace Phonon
void WorkerThread::handleTask()
{
- QMutexLocker locker(&m_mutex);
- if (m_finished || m_queue.isEmpty()) {
- return;
- }
+ {
+ QMutexLocker locker(&m_mutex);
+ if (m_finished || m_queue.isEmpty()) {
+ return;
+ }
- const Work w = m_queue.dequeue();
+ m_currentWork = m_queue.dequeue();
- //we ensure to have the wait condition in the right state
- if (m_queue.isEmpty()) {
- m_waitCondition.reset();
- } else {
- m_waitCondition.set();
+ //we ensure to have the wait condition in the right state
+ if (m_queue.isEmpty()) {
+ m_waitCondition.reset();
+ } else {
+ m_waitCondition.set();
+ }
}
HRESULT hr = S_OK;
- {
- QMutexLocker locker(&m_currentMutex);
- m_currentRender = w.graph;
- m_currentRenderId = w.id;
- }
- if (w.task == ReplaceGraph) {
+ if (m_currentWork.task == ReplaceGraph) {
int index = -1;
for(int i = 0; i < FILTER_COUNT; ++i) {
- if (m_graphHandle[i].graph == w.oldGraph) {
+ if (m_graphHandle[i].graph == m_currentWork.oldGraph) {
m_graphHandle[i].graph = Graph();
index = i;
break;
@@ -214,51 +212,39 @@ namespace Phonon
//add the new graph
HANDLE h;
- if (SUCCEEDED(ComPointer<IMediaEvent>(w.graph, IID_IMediaEvent)
+ if (SUCCEEDED(ComPointer<IMediaEvent>(m_currentWork.graph, IID_IMediaEvent)
->GetEventHandle(reinterpret_cast<OAEVENT*>(&h)))) {
- m_graphHandle[index].graph = w.graph;
+ m_graphHandle[index].graph = m_currentWork.graph;
m_graphHandle[index].handle = h;
}
- } else if (w.task == Render) {
- if (w.filter) {
+ } else if (m_currentWork.task == Render) {
+ if (m_currentWork.filter) {
//let's render pins
- w.graph->AddFilter(w.filter, 0);
- const QList<OutputPin> outputs = BackendNode::pins(w.filter, PINDIR_OUTPUT);
- for (int i = 0; i < outputs.count(); ++i) {
- //blocking call
- hr = w.graph->Render(outputs.at(i));
- if (FAILED(hr)) {
- break;
- }
+ const QList<OutputPin> outputs = BackendNode::pins(m_currentWork.filter, PINDIR_OUTPUT);
+ for (int i = 0; SUCCEEDED(hr) && i < outputs.count(); ++i) {
+ hr = m_currentWork.graph->Render(outputs.at(i));
}
- } else if (!w.url.isEmpty()) {
+ } else if (!m_currentWork.url.isEmpty()) {
//let's render a url (blocking call)
- hr = w.graph->RenderFile(reinterpret_cast<const wchar_t *>(w.url.utf16()), 0);
+ hr = m_currentWork.graph->RenderFile(reinterpret_cast<const wchar_t *>(m_currentWork.url.utf16()), 0);
}
if (hr != E_ABORT) {
- emit asyncRenderFinished(w.id, hr, w.graph);
+ emit asyncRenderFinished(m_currentWork.id, hr, m_currentWork.graph);
}
- } else if (w.task == Seek) {
+ } else if (m_currentWork.task == Seek) {
//that's a seekrequest
- ComPointer<IMediaSeeking> mediaSeeking(w.graph, IID_IMediaSeeking);
- qint64 newtime = w.time * 10000;
+ ComPointer<IMediaSeeking> mediaSeeking(m_currentWork.graph, IID_IMediaSeeking);
+ qint64 newtime = m_currentWork.time * 10000;
hr = mediaSeeking->SetPositions(&newtime, AM_SEEKING_AbsolutePositioning,
0, AM_SEEKING_NoPositioning);
- qint64 currentTime = -1;
- if (SUCCEEDED(hr)) {
- hr = mediaSeeking->GetCurrentPosition(&currentTime);
- if (SUCCEEDED(hr)) {
- currentTime /= 10000; //convert to ms
- }
- }
- emit asyncSeekingFinished(w.id, currentTime);
+ emit asyncSeekingFinished(m_currentWork.id, newtime / 10000);
hr = E_ABORT; //to avoid emitting asyncRenderFinished
- } else if (w.task == ChangeState) {
+ } else if (m_currentWork.task == ChangeState) {
//remove useless decoders
QList<Filter> unused;
- for (int i = 0; i < w.decoders.count(); ++i) {
- const Filter &filter = w.decoders.at(i);
+ for (int i = 0; i < m_currentWork.decoders.count(); ++i) {
+ const Filter &filter = m_currentWork.decoders.at(i);
bool used = false;
const QList<OutputPin> pins = BackendNode::pins(filter, PINDIR_OUTPUT);
for( int i = 0; i < pins.count(); ++i) {
@@ -275,15 +261,15 @@ namespace Phonon
//we can get the state
for (int i = 0; i < unused.count(); ++i) {
//we should remove this filter from the graph
- w.graph->RemoveFilter(unused.at(i));
+ m_currentWork.graph->RemoveFilter(unused.at(i));
}
//we can get the state
- ComPointer<IMediaControl> mc(w.graph, IID_IMediaControl);
+ ComPointer<IMediaControl> mc(m_currentWork.graph, IID_IMediaControl);
//we change the state here
- switch(w.state)
+ switch(m_currentWork.state)
{
case State_Stopped:
mc->Stop();
@@ -301,32 +287,27 @@ namespace Phonon
if (SUCCEEDED(hr)) {
if (s == State_Stopped) {
- emit stateReady(w.graph, Phonon::StoppedState);
+ emit stateReady(m_currentWork.graph, Phonon::StoppedState);
} else if (s == State_Paused) {
- emit stateReady(w.graph, Phonon::PausedState);
+ emit stateReady(m_currentWork.graph, Phonon::PausedState);
} else /*if (s == State_Running)*/ {
- emit stateReady(w.graph, Phonon::PlayingState);
+ emit stateReady(m_currentWork.graph, Phonon::PlayingState);
}
}
}
{
- QMutexLocker locker(&m_currentMutex);
- m_currentRender = Graph();
- m_currentRenderId = 0;
+ QMutexLocker locker(&m_mutex);
+ m_currentWork = Work(); //reinitialize
}
}
void WorkerThread::abortCurrentRender(qint16 renderId)
{
- {
- QMutexLocker locker(&m_currentMutex);
- if (m_currentRender && m_currentRenderId == renderId) {
- m_currentRender->Abort();
- }
- }
-
QMutexLocker locker(&m_mutex);
+ if (m_currentWork.id == renderId) {
+ m_currentWork.graph->Abort();
+ }
bool found = false;
for(int i = 0; !found && i < m_queue.size(); ++i) {
const Work &w = m_queue.at(i);
@@ -345,9 +326,9 @@ namespace Phonon
{
QMutexLocker locker(&m_mutex);
m_queue.clear();
- if (m_currentRender) {
+ if (m_currentWork.graph) {
//in case we're currently rendering something
- m_currentRender->Abort();
+ m_currentWork.graph->Abort();
}
@@ -835,8 +816,8 @@ namespace Phonon
#endif
LPAMGETERRORTEXT getErrorText = (LPAMGETERRORTEXT)QLibrary::resolve(QLatin1String("quartz"), "AMGetErrorTextW");
- ushort buffer[MAX_ERROR_TEXT_LEN];
- if (getErrorText && getErrorText(hr, (WCHAR*)buffer, MAX_ERROR_TEXT_LEN)) {
+ WCHAR buffer[MAX_ERROR_TEXT_LEN];
+ if (getErrorText && getErrorText(hr, buffer, MAX_ERROR_TEXT_LEN)) {
m_errorString = QString::fromUtf16(buffer);
} else {
m_errorString = QString::fromLatin1("Unknown error");
diff --git a/src/3rdparty/phonon/ds9/mediaobject.h b/src/3rdparty/phonon/ds9/mediaobject.h
index a6beb5f..34aa666 100644
--- a/src/3rdparty/phonon/ds9/mediaobject.h
+++ b/src/3rdparty/phonon/ds9/mediaobject.h
@@ -114,6 +114,7 @@ namespace Phonon
enum Task
{
+ None,
Render,
Seek,
ChangeState,
@@ -122,6 +123,7 @@ namespace Phonon
struct Work
{
+ Work() : task(None), id(0), time(0) { }
Task task;
quint16 id;
Graph graph;
@@ -137,14 +139,12 @@ namespace Phonon
};
void handleTask();
- Graph m_currentRender;
- qint16 m_currentRenderId;
+ Work m_currentWork;
QQueue<Work> m_queue;
bool m_finished;
quint16 m_currentWorkId;
QWinWaitCondition m_waitCondition;
QMutex m_mutex; // mutex for the m_queue, m_finished and m_currentWorkId
- QMutex m_currentMutex; //mutex for current renderer and id
//this is for WaitForMultipleObjects
struct