- 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.
This commit is contained in:
Robert Shearman 2004-08-19 02:33:00 +00:00 committed by Alexandre Julliard
parent 2300ce663a
commit 0aab65a1ef
2 changed files with 47 additions and 103 deletions

View File

@ -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);

View File

@ -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);
}