wineqtdecoder: Properly clean up splitter and loader threads on QTSplitter destruction.
This commit is contained in:
parent
96ace8636a
commit
2a4cab5375
|
@ -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());
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue