From 0aab65a1efa2a62e1fe564ccb2c4ea72cc479aeb Mon Sep 17 00:00:00 2001 From: Robert Shearman Date: Thu, 19 Aug 2004 02:33:00 +0000 Subject: [PATCH] - Remove duplicated code in file reader. - Use new CreateSpecific function for file reader that doesn't query for IMemInputPin. - Get rid of inefficient use of IMemInputPin in general pin code. --- dlls/quartz/filesource.c | 103 +++++++++++++++-------------------------------- dlls/quartz/pin.c | 47 +++++++-------------- 2 files changed, 47 insertions(+), 103 deletions(-) diff --git a/dlls/quartz/filesource.c b/dlls/quartz/filesource.c index 28c7fd113b5..ef8c3dae2ec 100644 --- a/dlls/quartz/filesource.c +++ b/dlls/quartz/filesource.c @@ -766,82 +766,13 @@ static HRESULT WINAPI FileAsyncReaderPin_EnumMediaTypes(IPin * iface, IEnumMedia return IEnumMediaTypesImpl_Construct(&emd, ppEnum); } -static HRESULT WINAPI FileAsyncReaderPin_Connect(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt) -{ - HRESULT hr = S_OK; - ICOM_THIS(OutputPin, iface); - - TRACE("(%p, %p)\n", pReceivePin, pmt); - dump_AM_MEDIA_TYPE(pmt); - - /* If we try to connect to ourself, we will definitely deadlock. - * There are other cases where we could deadlock too, but this - * catches the obvious case */ - assert(pReceivePin != iface); - - EnterCriticalSection(This->pin.pCritSec); - { - /* if we have been a specific type to connect with, then we can either connect - * with that or fail. We cannot choose different AM_MEDIA_TYPE */ - if (pmt && !IsEqualGUID(&pmt->majortype, &GUID_NULL) && !IsEqualGUID(&pmt->subtype, &GUID_NULL)) - hr = This->pConnectSpecific(iface, pReceivePin, pmt); - else - { - /* negotiate media type */ - - IEnumMediaTypes * pEnumCandidates; - AM_MEDIA_TYPE * pmtCandidate; /* Candidate media type */ - - if (SUCCEEDED(IPin_EnumMediaTypes(iface, &pEnumCandidates))) - { - hr = VFW_E_NO_ACCEPTABLE_TYPES; /* Assume the worst, but set to S_OK if connected successfully */ - - /* try this filter's media types first */ - while (S_OK == IEnumMediaTypes_Next(pEnumCandidates, 1, &pmtCandidate, NULL)) - { - if (( !pmt || CompareMediaTypes(pmt, pmtCandidate, TRUE) ) && - (This->pConnectSpecific(iface, pReceivePin, pmtCandidate) == S_OK)) - { - hr = S_OK; - CoTaskMemFree(pmtCandidate); - break; - } - CoTaskMemFree(pmtCandidate); - } - IEnumMediaTypes_Release(pEnumCandidates); - } - - /* then try receiver filter's media types */ - if (hr != S_OK && SUCCEEDED(IPin_EnumMediaTypes(pReceivePin, &pEnumCandidates))) /* if we haven't already connected successfully */ - { - while (S_OK == IEnumMediaTypes_Next(pEnumCandidates, 1, &pmtCandidate, NULL)) - { - if (( !pmt || CompareMediaTypes(pmt, pmtCandidate, TRUE) ) && - (This->pConnectSpecific(iface, pReceivePin, pmtCandidate) == S_OK)) - { - hr = S_OK; - CoTaskMemFree(pmtCandidate); - break; - } - CoTaskMemFree(pmtCandidate); - } /* while */ - IEnumMediaTypes_Release(pEnumCandidates); - } /* if not found */ - } /* if negotiate media type */ - } /* if succeeded */ - LeaveCriticalSection(This->pin.pCritSec); - - TRACE("-- %lx\n", hr); - return hr; -} - static const IPinVtbl FileAsyncReaderPin_Vtbl = { ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE FileAsyncReaderPin_QueryInterface, IPinImpl_AddRef, FileAsyncReaderPin_Release, - FileAsyncReaderPin_Connect, + OutputPin_Connect, OutputPin_ReceiveConnection, IPinImpl_Disconnect, IPinImpl_ConnectedTo, @@ -858,6 +789,37 @@ static const IPinVtbl FileAsyncReaderPin_Vtbl = OutputPin_NewSegment }; +/* Function called as a helper to IPin_Connect */ +/* specific AM_MEDIA_TYPE - it cannot be NULL */ +/* this differs from standard OutputPin_ConnectSpecific only in that it + * doesn't need the IMemInputPin interface on the receiving pin */ +static HRESULT FileAsyncReaderPin_ConnectSpecific(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt) +{ + ICOM_THIS(OutputPin, iface); + HRESULT hr; + + TRACE("(%p, %p)\n", pReceivePin, pmt); + dump_AM_MEDIA_TYPE(pmt); + + /* FIXME: call queryacceptproc */ + + This->pin.pConnectedTo = pReceivePin; + IPin_AddRef(pReceivePin); + CopyMediaType(&This->pin.mtCurrent, pmt); + + hr = IPin_ReceiveConnection(pReceivePin, iface, pmt); + + if (FAILED(hr)) + { + IPin_Release(This->pin.pConnectedTo); + This->pin.pConnectedTo = NULL; + DeleteMediaType(&This->pin.mtCurrent); + } + + TRACE(" -- %lx\n", hr); + return hr; +} + static HRESULT FileAsyncReader_Construct(HANDLE hFile, IBaseFilter * pBaseFilter, LPCRITICAL_SECTION pCritSec, IPin ** ppPin) { FileAsyncReader * pPinImpl; @@ -882,6 +844,7 @@ static HRESULT FileAsyncReader_Construct(HANDLE hFile, IBaseFilter * pBaseFilter pPinImpl->hEvent = CreateEventW(NULL, 0, 0, NULL); pPinImpl->bFlushing = FALSE; pPinImpl->pHead = NULL; + pPinImpl->pin.pConnectSpecific = FileAsyncReaderPin_ConnectSpecific; InitializeCriticalSection(&pPinImpl->csList); *ppPin = (IPin *)(&pPinImpl->pin.pin.lpVtbl); diff --git a/dlls/quartz/pin.c b/dlls/quartz/pin.c index 3e946cf7d95..f9684ef647b 100644 --- a/dlls/quartz/pin.c +++ b/dlls/quartz/pin.c @@ -52,7 +52,7 @@ static void Copy_PinInfo(PIN_INFO * pDest, const PIN_INFO * pSrc) IBaseFilter_AddRef(pDest->pFilter); } -/* Internal function called as a helper to IPin_Connect */ +/* Function called as a helper to IPin_Connect */ /* specific AM_MEDIA_TYPE - it cannot be NULL */ /* NOTE: not part of standard interface */ static HRESULT OutputPin_ConnectSpecific(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt) @@ -842,14 +842,9 @@ HRESULT OutputPin_GetDeliveryBuffer(OutputPin * This, IMediaSample ** ppSample, hr = VFW_E_NOT_CONNECTED; else { - IMemInputPin * pMemInputPin = NULL; IMemAllocator * pAlloc = NULL; - /* FIXME: should we cache this? */ - hr = IPin_QueryInterface(This->pin.pConnectedTo, &IID_IMemInputPin, (LPVOID *)&pMemInputPin); - - if (SUCCEEDED(hr)) - hr = IMemInputPin_GetAllocator(pMemInputPin, &pAlloc); + hr = IMemInputPin_GetAllocator(This->pMemInputPin, &pAlloc); if (SUCCEEDED(hr)) hr = IMemAllocator_GetBuffer(pAlloc, ppSample, (REFERENCE_TIME *)tStart, (REFERENCE_TIME *)tStop, dwFlags); @@ -859,8 +854,6 @@ HRESULT OutputPin_GetDeliveryBuffer(OutputPin * This, IMediaSample ** ppSample, if (pAlloc) IMemAllocator_Release(pAlloc); - if (pMemInputPin) - IMemInputPin_Release(pMemInputPin); } } LeaveCriticalSection(This->pin.pCritSec); @@ -870,23 +863,25 @@ HRESULT OutputPin_GetDeliveryBuffer(OutputPin * This, IMediaSample ** ppSample, HRESULT OutputPin_SendSample(OutputPin * This, IMediaSample * pSample) { - HRESULT hr; + HRESULT hr = S_OK; IMemInputPin * pMemConnected = NULL; EnterCriticalSection(This->pin.pCritSec); { - if (!This->pin.pConnectedTo) + if (!This->pin.pConnectedTo || !This->pMemInputPin) hr = VFW_E_NOT_CONNECTED; else { - /* FIXME: should we cache this? - if we do, then we need to keep the local version - * and AddRef here instead */ - hr = IPin_QueryInterface(This->pin.pConnectedTo, &IID_IMemInputPin, (LPVOID *)&pMemConnected); + /* we don't have the lock held when using This->pMemInputPin, + * so we need to AddRef it to stop it being deleted while we are + * using it. */ + pMemConnected = This->pMemInputPin; + IMemInputPin_AddRef(pMemConnected); } } LeaveCriticalSection(This->pin.pCritSec); - if (SUCCEEDED(hr) && pMemConnected) + if (SUCCEEDED(hr)) { /* NOTE: if we are in a critical section when Receive is called * then it causes some problems (most notably with the native Video @@ -922,26 +917,19 @@ HRESULT OutputPin_CommitAllocator(OutputPin * This) EnterCriticalSection(This->pin.pCritSec); { - if (!This->pin.pConnectedTo) + if (!This->pin.pConnectedTo || !This->pMemInputPin) hr = VFW_E_NOT_CONNECTED; else { - IMemInputPin * pMemInputPin = NULL; IMemAllocator * pAlloc = NULL; - /* FIXME: should we cache this? */ - hr = IPin_QueryInterface(This->pin.pConnectedTo, &IID_IMemInputPin, (LPVOID *)&pMemInputPin); - if (SUCCEEDED(hr)) - hr = IMemInputPin_GetAllocator(pMemInputPin, &pAlloc); + hr = IMemInputPin_GetAllocator(This->pMemInputPin, &pAlloc); if (SUCCEEDED(hr)) hr = IMemAllocator_Commit(pAlloc); if (pAlloc) IMemAllocator_Release(pAlloc); - - if (pMemInputPin) - IMemInputPin_Release(pMemInputPin); } } LeaveCriticalSection(This->pin.pCritSec); @@ -957,17 +945,13 @@ HRESULT OutputPin_DeliverDisconnect(OutputPin * This) EnterCriticalSection(This->pin.pCritSec); { - if (!This->pin.pConnectedTo) + if (!This->pin.pConnectedTo || !This->pMemInputPin) hr = VFW_E_NOT_CONNECTED; else { - IMemInputPin * pMemInputPin = NULL; IMemAllocator * pAlloc = NULL; - /* FIXME: should we cache this? */ - hr = IPin_QueryInterface(This->pin.pConnectedTo, &IID_IMemInputPin, (LPVOID *)&pMemInputPin); - if (SUCCEEDED(hr)) - hr = IMemInputPin_GetAllocator(pMemInputPin, &pAlloc); + hr = IMemInputPin_GetAllocator(This->pMemInputPin, &pAlloc); if (SUCCEEDED(hr)) hr = IMemAllocator_Decommit(pAlloc); @@ -975,9 +959,6 @@ HRESULT OutputPin_DeliverDisconnect(OutputPin * This) if (pAlloc) IMemAllocator_Release(pAlloc); - if (pMemInputPin) - IMemInputPin_Release(pMemInputPin); - if (SUCCEEDED(hr)) hr = IPin_Disconnect(This->pin.pConnectedTo); } -- 2.11.4.GIT