Quartz: Fix For IAsyncReader Output Pin (resend)
Robert Shearman
rob at codeweavers.com
Wed Aug 18 19:46:27 CDT 2004
This time without the conflicts with current CVS.
Changelog:
- 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.
-------------- next part --------------
Index: wine/dlls/quartz/filesource.c
===================================================================
RCS file: /home/wine/wine/dlls/quartz/filesource.c,v
retrieving revision 1.6
diff -u -p -r1.6 filesource.c
--- wine/dlls/quartz/filesource.c 13 Aug 2004 19:49:16 -0000 1.6
+++ wine/dlls/quartz/filesource.c 19 Aug 2004 00:43:07 -0000
@@ -766,82 +766,13 @@ static HRESULT WINAPI FileAsyncReaderPin
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
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
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);
Index: wine/dlls/quartz/pin.c
===================================================================
RCS file: /home/wine/wine/dlls/quartz/pin.c,v
retrieving revision 1.5
diff -u -p -r1.5 pin.c
--- wine/dlls/quartz/pin.c 16 Aug 2004 21:07:22 -0000 1.5
+++ wine/dlls/quartz/pin.c 19 Aug 2004 00:43:07 -0000
@@ -52,7 +52,7 @@ static void Copy_PinInfo(PIN_INFO * pDes
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(Outp
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(Outp
if (pAlloc)
IMemAllocator_Release(pAlloc);
- if (pMemInputPin)
- IMemInputPin_Release(pMemInputPin);
}
}
LeaveCriticalSection(This->pin.pCritSec);
@@ -870,23 +863,25 @@ HRESULT OutputPin_GetDeliveryBuffer(Outp
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(Output
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,26 +945,19 @@ HRESULT OutputPin_DeliverDisconnect(Outp
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);
if (pAlloc)
IMemAllocator_Release(pAlloc);
-
- if (pMemInputPin)
- IMemInputPin_Release(pMemInputPin);
if (SUCCEEDED(hr))
hr = IPin_Disconnect(This->pin.pConnectedTo);
More information about the wine-patches
mailing list