From a4d59a9c13cae29448aefb0bce0413d6c818a8cd Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Tue, 24 Jun 2008 08:52:52 -0700 Subject: [PATCH] quartz: Create thread after connection is made --- dlls/quartz/parser.c | 33 +++--------- dlls/quartz/pin.c | 127 +++++++++++----------------------------------- dlls/quartz/pin.h | 3 +- dlls/quartz/waveparser.c | 2 +- 4 files changed, 38 insertions(+), 127 deletions(-) diff --git a/dlls/quartz/parser.c b/dlls/quartz/parser.c index 33e3d04..97be991 100644 --- a/dlls/quartz/parser.c +++ b/dlls/quartz/parser.c @@ -217,7 +217,6 @@ HRESULT WINAPI Parser_GetClassID(IBaseFilter * iface, CLSID * pClsid) HRESULT WINAPI Parser_Stop(IBaseFilter * iface) { - HRESULT hr; ParserImpl *This = (ParserImpl *)iface; PullPin *pin = (PullPin *)This->ppPins[0]; @@ -226,19 +225,11 @@ HRESULT WINAPI Parser_Stop(IBaseFilter * iface) EnterCriticalSection(&pin->thread_lock); EnterCriticalSection(&This->csFilter); { - if (This->state == State_Stopped) - { - LeaveCriticalSection(&This->csFilter); - LeaveCriticalSection(&pin->thread_lock); - return S_OK; - } This->state = State_Stopped; } LeaveCriticalSection(&This->csFilter); - - hr = PullPin_StopProcessing(This->pInputPin); LeaveCriticalSection(&pin->thread_lock); - return hr; + return S_OK; } HRESULT WINAPI Parser_Pause(IBaseFilter * iface) @@ -300,16 +291,9 @@ HRESULT WINAPI Parser_Run(IBaseFilter * iface, REFERENCE_TIME tStart) if (SUCCEEDED(hr) && (This->state == State_Stopped)) { - LeaveCriticalSection(&This->csFilter); - hr = PullPin_InitProcessing(This->pInputPin); - EnterCriticalSection(&This->csFilter); - - if (SUCCEEDED(hr)) - { - for (i = 1; i < (This->cStreams + 1); i++) - { - OutputPin_CommitAllocator((OutputPin *)This->ppPins[i]); - } + for (i = 1; i < (This->cStreams + 1); i++) + { + OutputPin_CommitAllocator((OutputPin *)This->ppPins[i]); } } @@ -714,7 +698,6 @@ static HRESULT WINAPI Parser_PullPin_Disconnect(IPin * iface) { if (This->pin.pConnectedTo) { - PullPin *ppin = (PullPin *)This; FILTER_STATE state; ParserImpl *Parser = (ParserImpl *)This->pin.pinInfo.pFilter; @@ -724,11 +707,9 @@ static HRESULT WINAPI Parser_PullPin_Disconnect(IPin * iface) if (SUCCEEDED(hr) && (state == State_Stopped) && SUCCEEDED(Parser->fnDisconnect(Parser))) { - IPin_Release(This->pin.pConnectedTo); - This->pin.pConnectedTo = NULL; - - if (FAILED(hr = IMemAllocator_Decommit(ppin->pAlloc))) - ERR("Allocator decommit failed with error %x. Possible memory leak\n", hr); + LeaveCriticalSection(This->pin.pCritSec); + PullPin_Disconnect(iface); + EnterCriticalSection(This->pin.pCritSec); hr = Parser_RemoveOutputPins((ParserImpl *)This->pin.pinInfo.pFilter); } else diff --git a/dlls/quartz/pin.c b/dlls/quartz/pin.c index edf321d..5bce9bb 100644 --- a/dlls/quartz/pin.c +++ b/dlls/quartz/pin.c @@ -1277,6 +1277,8 @@ HRESULT PullPin_Construct(const IPinVtbl *PullPin_Vtbl, const PIN_INFO * pPinInf return E_FAIL; } +static HRESULT PullPin_InitProcessing(PullPin * This); + HRESULT WINAPI PullPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt) { PIN_DIRECTION pindirReceive; @@ -1334,9 +1336,11 @@ HRESULT WINAPI PullPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const This->pin.pConnectedTo = pReceivePin; IPin_AddRef(pReceivePin); hr = IMemAllocator_Commit(This->pAlloc); - } + if (SUCCEEDED(hr)) + hr = PullPin_InitProcessing(This); + if (FAILED(hr)) { if (This->pReader) @@ -1407,44 +1411,6 @@ ULONG WINAPI PullPin_Release(IPin *iface) return refCount; } -static HRESULT PullPin_Standard_Request(PullPin *This, BOOL start) -{ - REFERENCE_TIME rtSampleStart; - REFERENCE_TIME rtSampleStop; - IMediaSample *sample = NULL; - HRESULT hr; - - TRACE("Requesting sample!\n"); - - if (start) - This->rtNext = This->rtCurrent; - - if (This->rtNext >= This->rtStop) - /* Last sample has already been queued, request nothing more */ - return S_OK; - - hr = IMemAllocator_GetBuffer(This->pAlloc, &sample, NULL, NULL, 0); - - if (SUCCEEDED(hr)) - { - rtSampleStart = This->rtNext; - rtSampleStop = rtSampleStart + MEDIATIME_FROM_BYTES(IMediaSample_GetSize(sample)); - if (rtSampleStop > This->rtStop) - rtSampleStop = MEDIATIME_FROM_BYTES(ALIGNUP(BYTES_FROM_MEDIATIME(This->rtStop), This->cbAlign)); - hr = IMediaSample_SetTime(sample, &rtSampleStart, &rtSampleStop); - - This->rtCurrent = This->rtNext; - This->rtNext = rtSampleStop; - - if (SUCCEEDED(hr)) - hr = IAsyncReader_Request(This->pReader, sample, 0); - } - if (FAILED(hr)) - FIXME("Failed to queue sample : %08x\n", hr); - - return hr; -} - static void CALLBACK PullPin_Flush(PullPin *This) { IMediaSample *pSample; @@ -1465,8 +1431,6 @@ static void CALLBACK PullPin_Flush(PullPin *This) break; assert(!IMediaSample_GetActualDataLength(pSample)); - if (This->fnCustomRequest) - This->fnSampleProc(This->pin.pUserData, pSample, dwUser); IMediaSample_Release(pSample); } @@ -1476,7 +1440,7 @@ static void CALLBACK PullPin_Flush(PullPin *This) LeaveCriticalSection(This->pin.pCritSec); } -static void CALLBACK PullPin_Thread_Process(PullPin *This) +static void CALLBACK PullPin_Thread_Process(PullPin *This, BOOL pause) { HRESULT hr; IMediaSample * pSample = NULL; @@ -1498,18 +1462,19 @@ static void CALLBACK PullPin_Thread_Process(PullPin *This) } /* There is no sample in our buffer */ - if (!This->fnCustomRequest) - hr = PullPin_Standard_Request(This, TRUE); - else - hr = This->fnCustomRequest(This->pin.pUserData); + hr = This->fnCustomRequest(This->pin.pUserData); if (FAILED(hr)) ERR("Request error: %x\n", hr); - EnterCriticalSection(This->pin.pCritSec); - SetEvent(This->hEventStateChanged); - LeaveCriticalSection(This->pin.pCritSec); + if (!pause) + { + EnterCriticalSection(This->pin.pCritSec); + SetEvent(This->hEventStateChanged); + LeaveCriticalSection(This->pin.pCritSec); + } + if (SUCCEEDED(hr)) do { DWORD_PTR dwUser; @@ -1518,41 +1483,10 @@ static void CALLBACK PullPin_Thread_Process(PullPin *This) hr = IAsyncReader_WaitForNext(This->pReader, 10000, &pSample, &dwUser); - /* Calling fnCustomRequest is not specifically useful here: It can be handled inside fnSampleProc */ - if (pSample && !This->fnCustomRequest) - hr = PullPin_Standard_Request(This, FALSE); - /* Return an empty sample on error to the implementation in case it does custom parsing, so it knows it's gone */ - if (SUCCEEDED(hr) || (This->fnCustomRequest && pSample)) + if (SUCCEEDED(hr)) { - REFERENCE_TIME rtStart, rtStop; - BOOL rejected; - - IMediaSample_GetTime(pSample, &rtStart, &rtStop); - - do - { - hr = This->fnSampleProc(This->pin.pUserData, pSample, dwUser); - - if (This->fnCustomRequest) - break; - - rejected = FALSE; - if (This->rtCurrent == rtStart) - { - rejected = TRUE; - TRACE("DENIED!\n"); - Sleep(10); - /* Maybe it's transient? */ - } - /* rtNext = rtCurrent, because the next sample is already queued */ - else if (rtStop != This->rtCurrent && rtStop < This->rtStop) - { - WARN("Position changed! rtStop: %u, rtCurrent: %u\n", (DWORD)BYTES_FROM_MEDIATIME(rtStop), (DWORD)BYTES_FROM_MEDIATIME(This->rtCurrent)); - PullPin_Flush(This); - hr = PullPin_Standard_Request(This, TRUE); - } - } while (rejected && (This->rtCurrent < This->rtStop && hr == S_OK && !This->stop_playback)); + hr = This->fnSampleProc(This->pin.pUserData, pSample, dwUser); } else { @@ -1580,21 +1514,17 @@ static void CALLBACK PullPin_Thread_Process(PullPin *This) if (This->fnDone) This->fnDone(This->pin.pUserData); - PullPin_Flush(This); - - TRACE("End: %08x, %d\n", hr, This->stop_playback); -} - -static void CALLBACK PullPin_Thread_Pause(PullPin *This) -{ - TRACE("(%p)->()\n", This); - EnterCriticalSection(This->pin.pCritSec); + if (pause) { + EnterCriticalSection(This->pin.pCritSec); This->state = Req_Sleepy; SetEvent(This->hEventStateChanged); + LeaveCriticalSection(This->pin.pCritSec); } - LeaveCriticalSection(This->pin.pCritSec); + + + TRACE("End: %08x, %d\n", hr, This->stop_playback); } static void CALLBACK PullPin_Thread_Stop(PullPin *This) @@ -1620,6 +1550,8 @@ static DWORD WINAPI PullPin_Thread_Main(LPVOID pv) PullPin *This = pv; CoInitializeEx(NULL, COINIT_MULTITHREADED); + PullPin_Flush(This); + for (;;) { WaitForSingleObject(This->thread_sleepy, INFINITE); @@ -1629,15 +1561,15 @@ static DWORD WINAPI PullPin_Thread_Main(LPVOID pv) switch (This->state) { case Req_Die: PullPin_Thread_Stop(This); break; - case Req_Run: PullPin_Thread_Process(This); break; - case Req_Pause: PullPin_Thread_Pause(This); break; + case Req_Run: PullPin_Thread_Process(This, FALSE); break; + case Req_Pause: PullPin_Thread_Process(This, TRUE); break; case Req_Sleepy: ERR("Should not be signalled with SLEEPY!\n"); break; default: ERR("Unknown state request: %d\n", This->state); break; } } } -HRESULT PullPin_InitProcessing(PullPin * This) +static HRESULT PullPin_InitProcessing(PullPin * This) { HRESULT hr = S_OK; @@ -1716,8 +1648,6 @@ HRESULT PullPin_PauseProcessing(PullPin * This) PullPin_WaitForStateChange(This, INFINITE); EnterCriticalSection(This->pin.pCritSec); - /* Faster! */ - IAsyncReader_BeginFlush(This->pReader); assert(!This->stop_playback); assert(This->state == Req_Run|| This->state == Req_Sleepy); @@ -1734,7 +1664,7 @@ HRESULT PullPin_PauseProcessing(PullPin * This) return S_OK; } -HRESULT PullPin_StopProcessing(PullPin * This) +static HRESULT PullPin_StopProcessing(PullPin * This) { TRACE("(%p)->()\n", This); @@ -1840,6 +1770,7 @@ HRESULT WINAPI PullPin_Disconnect(IPin *iface) { IPin_Release(This->pin.pConnectedTo); This->pin.pConnectedTo = NULL; + PullPin_StopProcessing(This); hr = S_OK; } else diff --git a/dlls/quartz/pin.h b/dlls/quartz/pin.h index 6d0600e..b67ff1b 100644 --- a/dlls/quartz/pin.h +++ b/dlls/quartz/pin.h @@ -204,6 +204,7 @@ HRESULT WINAPI MemInputPin_ReceiveCanBlock(IMemInputPin * iface); /* Pull Pin */ HRESULT WINAPI PullPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt); +HRESULT WINAPI PullPin_Disconnect(IPin * iface); HRESULT WINAPI PullPin_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv); ULONG WINAPI PullPin_Release(IPin * iface); HRESULT WINAPI PullPin_EndOfStream(IPin * iface); @@ -212,8 +213,6 @@ HRESULT WINAPI PullPin_EndFlush(IPin * iface); HRESULT WINAPI PullPin_NewSegment(IPin * iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate); /* Thread interaction functions: Hold the thread_lock before calling them */ -HRESULT PullPin_InitProcessing(PullPin * This); HRESULT PullPin_StartProcessing(PullPin * This); -HRESULT PullPin_StopProcessing(PullPin * This); HRESULT PullPin_PauseProcessing(PullPin * This); HRESULT PullPin_WaitForStateChange(PullPin * This, DWORD dwMilliseconds); diff --git a/dlls/quartz/waveparser.c b/dlls/quartz/waveparser.c index 9c5e6fa..dbc096c 100644 --- a/dlls/quartz/waveparser.c +++ b/dlls/quartz/waveparser.c @@ -381,7 +381,7 @@ static HRESULT WAVEParser_first_request(LPVOID iface) hr = IAsyncReader_Request(pin->pReader, sample, 0); } if (FAILED(hr)) - ERR("Horsemen of the apocalypse came to bring error 0x%08x\n", hr); + ERR("Horsemen of the apocalypse came to bring error 0x%08x %p\n", hr, sample); return hr; } -- 1.5.4.1