mirror of
https://github.com/reactos/wine.git
synced 2024-11-25 20:59:54 +00:00
- 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:
parent
2300ce663a
commit
0aab65a1ef
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user