wineqtdecoder: Properly clean up splitter and loader threads on QTSplitter destruction.

This commit is contained in:
Aric Stewart 2012-11-20 08:08:36 -06:00 committed by Alexandre Julliard
parent 96ace8636a
commit 2a4cab5375
1 changed files with 42 additions and 14 deletions

View File

@ -168,6 +168,9 @@ typedef struct QTSplitter {
TimeValue movie_time; TimeValue movie_time;
TimeValue movie_start; TimeValue movie_start;
TimeScale movie_scale; TimeScale movie_scale;
HANDLE loaderThread;
HANDLE splitterThread;
} QTSplitter; } QTSplitter;
static const IPinVtbl QT_OutputPin_Vtbl; static const IPinVtbl QT_OutputPin_Vtbl;
@ -293,6 +296,7 @@ static void QT_Destroy(QTSplitter *This)
TRACE("Destroying\n"); TRACE("Destroying\n");
EnterCriticalSection(&This->csReceive);
/* Don't need to clean up output pins, disconnecting input pin will do that */ /* Don't need to clean up output pins, disconnecting input pin will do that */
IPin_ConnectedTo(&This->pInputPin.pin.IPin_iface, &connected); IPin_ConnectedTo(&This->pInputPin.pin.IPin_iface, &connected);
if (connected) if (connected)
@ -311,14 +315,31 @@ static void QT_Destroy(QTSplitter *This)
} }
if (This->pQTMovie) if (This->pQTMovie)
{
DisposeMovie(This->pQTMovie); DisposeMovie(This->pQTMovie);
This->pQTMovie = NULL;
}
if (This->vContext) if (This->vContext)
QTVisualContextRelease(This->vContext); QTVisualContextRelease(This->vContext);
if (This->aSession) if (This->aSession)
MovieAudioExtractionEnd(This->aSession); MovieAudioExtractionEnd(This->aSession);
CloseHandle(This->runEvent);
ExitMovies(); ExitMovies();
LeaveCriticalSection(&This->csReceive);
if (This->loaderThread)
{
WaitForSingleObject(This->loaderThread, INFINITE);
CloseHandle(This->loaderThread);
}
if (This->splitterThread)
{
SetEvent(This->runEvent);
WaitForSingleObject(This->splitterThread, INFINITE);
CloseHandle(This->splitterThread);
}
CloseHandle(This->runEvent);
This->csReceive.DebugInfo->Spare[0] = 0; This->csReceive.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&This->csReceive); DeleteCriticalSection(&This->csReceive);
@ -495,13 +516,15 @@ static DWORD WINAPI QTSplitter_loading_thread(LPVOID data)
to try to minimize that. to try to minimize that.
*/ */
while(GetMovieLoadState(This->pQTMovie) < kMovieLoadStateComplete) EnterCriticalSection(&This->csReceive);
while(This->pQTMovie && GetMovieLoadState(This->pQTMovie) < kMovieLoadStateComplete)
{ {
EnterCriticalSection(&This->csReceive);
MoviesTask(This->pQTMovie, 100); MoviesTask(This->pQTMovie, 100);
LeaveCriticalSection(&This->csReceive); LeaveCriticalSection(&This->csReceive);
Sleep(0); Sleep(0);
EnterCriticalSection(&This->csReceive);
} }
LeaveCriticalSection(&This->csReceive);
} }
return 0; return 0;
} }
@ -518,6 +541,12 @@ static DWORD WINAPI QTSplitter_thread(LPVOID data)
WaitForSingleObject(This->runEvent, -1); WaitForSingleObject(This->runEvent, -1);
EnterCriticalSection(&This->csReceive); EnterCriticalSection(&This->csReceive);
if (!This->pQTMovie)
{
LeaveCriticalSection(&This->csReceive);
return 0;
}
This->state = State_Running; This->state = State_Running;
/* Prime the pump: Needed for MPEG streams */ /* Prime the pump: Needed for MPEG streams */
GetMovieNextInterestingTime(This->pQTMovie, nextTimeEdgeOK | nextTimeStep, 0, NULL, This->movie_time, 1, &next_time, NULL); GetMovieNextInterestingTime(This->pQTMovie, nextTimeEdgeOK | nextTimeStep, 0, NULL, This->movie_time, 1, &next_time, NULL);
@ -536,6 +565,12 @@ static DWORD WINAPI QTSplitter_thread(LPVOID data)
float time; float time;
EnterCriticalSection(&This->csReceive); EnterCriticalSection(&This->csReceive);
if (!This->pQTMovie)
{
LeaveCriticalSection(&This->csReceive);
return 0;
}
GetMovieNextInterestingTime(This->pQTMovie, nextTimeStep, 0, NULL, This->movie_time, 1, &next_time, NULL); GetMovieNextInterestingTime(This->pQTMovie, nextTimeStep, 0, NULL, This->movie_time, 1, &next_time, NULL);
if (next_time == -1) if (next_time == -1)
@ -992,7 +1027,6 @@ static HRESULT QT_Process_Movie(QTSplitter* filter)
Track trk; Track trk;
short id = 0; short id = 0;
DWORD tid; DWORD tid;
HANDLE thread;
LONGLONG time; LONGLONG time;
TRACE("Trying movie connect\n"); TRACE("Trying movie connect\n");
@ -1039,18 +1073,12 @@ static HRESULT QT_Process_Movie(QTSplitter* filter)
TRACE("Movie duration is %s\n",wine_dbgstr_longlong(filter->sourceSeeking.llDuration)); TRACE("Movie duration is %s\n",wine_dbgstr_longlong(filter->sourceSeeking.llDuration));
thread = CreateThread(NULL, 0, QTSplitter_loading_thread, filter, 0, &tid); filter->loaderThread = CreateThread(NULL, 0, QTSplitter_loading_thread, filter, 0, &tid);
if (thread) if (filter->loaderThread)
{
TRACE("Created loading thread 0x%08x\n", tid); TRACE("Created loading thread 0x%08x\n", tid);
CloseHandle(thread); filter->splitterThread = CreateThread(NULL, 0, QTSplitter_thread, filter, 0, &tid);
} if (filter->splitterThread)
thread = CreateThread(NULL, 0, QTSplitter_thread, filter, 0, &tid);
if (thread)
{
TRACE("Created processing thread 0x%08x\n", tid); TRACE("Created processing thread 0x%08x\n", tid);
CloseHandle(thread);
}
else else
hr = HRESULT_FROM_WIN32(GetLastError()); hr = HRESULT_FROM_WIN32(GetLastError());