Some fixes for filtergraph.c (#3)
Maarten Lankhorst
m.b.lankhorst at gmail.com
Mon Apr 25 10:55:56 CDT 2005
Added critical section around the mediacontrols, also added a release
for the attached filters when the filtergraph gets released, so ref
count leak has decreased.. I also submitted a patch to devenum to fix
another release error, as a matter of fact:
fixme:quartz:ReadThread 0x7d331c20 -> Frame 4: 0
fixme:quartz:ReadThread 0x7d331c20 -> Frame 5: 0
fixme:quartz:Capture_Pause 0x7d331c20 -> (0x7d331d60) stub
fixme:quartz:Capture_Stop 0x7d331c20 -> (0x7d331d60) stub
fixme:quartz:CaptureGraphBuilder_Release Release IGraphFilter or w/e
fixme:quartz:VfwCapture_Release (0x7d331c18/0x7d331c18)->() Old refcount: 2
fixme:quartz:VfwCapture_Release (0x7d331c18/0x7d331c18)->() Old refcount: 1
with those patches, VfwCapture is now being released normally, without
reference leaks :):):)
Actually, 1 fix has to be made in pin.c
Copy_PinInfo is used by QueryPinInfo and internally, in QueryPinInfo,
the basefilter needs an addref there, but other internal functions
shouldn't, a pin SHOULDN'T need to add an addref to it's filter, it will
cause a deadrefcount (or something like that)
Because:
IFilter created, refcount 1,
IPin created, refcount 1,
IPin adds refcount to ifilter, ifilter refcount 2
IFilter released, refcount 1, continues existing, pin not being
destroyed, nobody ever knew it existed
I also added a fix for dlls/devenum/mediacatenum.c, which also has a
refcount leak when querying an interface
I hope these patches get applied, because they should.. and I don't want
to spend any more minute to them...
-------------- next part --------------
Index: filtergraph.c
===================================================================
RCS file: /home/wine/wine/dlls/quartz/filtergraph.c,v
retrieving revision 1.27
diff -u -p -r1.27 filtergraph.c
--- filtergraph.c 24 Mar 2005 21:01:37 -0000 1.27
+++ filtergraph.c 25 Apr 2005 15:33:51 -0000
@@ -245,6 +245,9 @@ static ULONG Filtergraph_Release(IFilter
TRACE("(%p)->(): new ref = %ld\n", This, ref);
if (ref == 0) {
+ int i;
+ for (i = 0; i < This->nFilters; i++)
+ IBaseFilter_Release(This->ppFiltersInGraph[i]);
IFilterMapper2_Release(This->pFilterMapper2);
CloseHandle(This->hEventCompletion);
EventsQueue_Destroy(&This->evqueue);
@@ -556,8 +559,7 @@ static HRESULT GetInternalConnections(IB
IPin_QueryDirection(ppin, &pindir);
if (pindir == PINDIR_OUTPUT)
i++;
- else
- IPin_Release(ppin);
+ IPin_Release(ppin);
}
*pppins = CoTaskMemAlloc(sizeof(IPin*)*i);
/* Retrieve output pins */
@@ -648,7 +650,7 @@ static HRESULT WINAPI Graphbuilder_Conne
VARIANT var;
GUID clsid;
IPin** ppins;
- IPin* ppinfilter;
+ IPin* ppinfilter = NULL;
IBaseFilter* pfilter = NULL;
hr = GetFilterInfo(pMoniker, &clsid, &var);
@@ -677,6 +679,7 @@ static HRESULT WINAPI Graphbuilder_Conne
ERR("Enumpins (%lx)\n", hr);
goto error;
}
+
hr = IEnumPins_Next(penumpins, 1, &ppinfilter, &pin);
if (FAILED(hr)) {
ERR("Next (%lx)\n", hr);
@@ -703,17 +706,22 @@ static HRESULT WINAPI Graphbuilder_Conne
TRACE("pins to consider: %ld\n", nb);
for(i = 0; i < nb; i++) {
TRACE("Processing pin %d\n", i);
- hr = IGraphBuilder_Connect(iface, ppins[0], ppinIn);
+ hr = IGraphBuilder_Connect(iface, ppins[i], ppinIn);
if (FAILED(hr)) {
- TRACE("Cannot render pin %p (%lx)\n", ppinfilter, hr);
- return hr;
+ TRACE("Cannot render pin %p (%lx)\n", ppinfilter, hr);
}
+ IPin_Release(ppins[i]);
+ if (SUCCEEDED(hr)) break;
}
+ while (++i < nb) IPin_Release(ppins[i]);
CoTaskMemFree(ppins);
+ IBaseFilter_Release(pfilter);
+ IPin_Release(ppinfilter);
+ break;
}
- break;
error:
+ if (ppinfilter) IPin_Release(ppinfilter);
if (pfilter) {
IGraphBuilder_RemoveFilter(iface, pfilter);
IBaseFilter_Release(pfilter);
@@ -1167,7 +1175,9 @@ static HRESULT WINAPI Mediacontrol_Invok
return S_OK;
}
-static HRESULT ExploreGraph(IFilterGraphImpl* pGraph, IPin* pOutputPin, REFERENCE_TIME tStart)
+typedef HRESULT(WINAPI *fnFoundFilter)(IBaseFilter *);
+
+static HRESULT ExploreGraph(IFilterGraphImpl* pGraph, IPin* pOutputPin, fnFoundFilter FoundFilter)
{
HRESULT hr;
IPin* pInputPin;
@@ -1176,7 +1186,8 @@ static HRESULT ExploreGraph(IFilterGraph
ULONG i;
PIN_INFO PinInfo;
- TRACE("%p %p %lld\n", pGraph, pOutputPin, tStart);
+ TRACE("%p %p\n", pGraph, pOutputPin);
+ PinInfo.pFilter = NULL;
hr = IPin_ConnectedTo(pOutputPin, &pInputPin);
@@ -1201,20 +1212,33 @@ static HRESULT ExploreGraph(IFilterGraph
/* Explore the graph downstream from this pin
* FIXME: We should prevent exploring from a pin more than once. This can happens when
* several input pins are connected to the same output (a MUX for instance). */
- ExploreGraph(pGraph, ppPins[i], tStart);
+ ExploreGraph(pGraph, ppPins[i], FoundFilter);
+ IPin_Release(ppPins[i]);
}
CoTaskMemFree(ppPins);
}
- TRACE("Run filter %p\n", PinInfo.pFilter);
- IBaseFilter_Run(PinInfo.pFilter, tStart);
+ TRACE("Doing stuff with filter %p\n", PinInfo.pFilter);
+ FoundFilter(PinInfo.pFilter);
}
+ if (PinInfo.pFilter) IBaseFilter_Release(PinInfo.pFilter);
return hr;
}
-/*** IMediaControl methods ***/
-static HRESULT WINAPI Mediacontrol_Run(IMediaControl *iface) {
+static HRESULT WINAPI SendRun(IBaseFilter *pFilter) {
+ return IBaseFilter_Run(pFilter, 0);
+}
+
+static HRESULT WINAPI SendPause(IBaseFilter *pFilter) {
+ return IBaseFilter_Pause(pFilter);
+}
+
+static HRESULT WINAPI SendStop(IBaseFilter *pFilter) {
+ return IBaseFilter_Stop(pFilter);
+}
+
+static HRESULT WINAPI SendTheFilterAMessage(IMediaControl *iface, fnFoundFilter FoundFilter) {
ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
int i;
IBaseFilter* pfilter;
@@ -1223,19 +1247,10 @@ static HRESULT WINAPI Mediacontrol_Run(I
IPin* pPin;
LONG dummy;
PIN_DIRECTION dir;
-
TRACE("(%p/%p)->()\n", This, iface);
- EnterCriticalSection(&This->cs);
-
- if (This->state == State_Running)
- {
- LeaveCriticalSection(&This->cs);
- return S_OK;
- }
-
- /* Explorer the graph from source filters to renderers, determine renderers number and
- * run filters from renderers to source filters */
+ /* Explorer the graph from source filters to renderers, determine renderers
+ * number and run filters from renderers to source filters */
This->nRenderers = 0;
ResetEvent(This->hEventCompletion);
@@ -1253,6 +1268,7 @@ static HRESULT WINAPI Mediacontrol_Run(I
while(IEnumPins_Next(pEnum, 1, &pPin, &dummy) == S_OK)
{
IPin_QueryDirection(pPin, &dir);
+ IPin_Release(pPin);
if (dir == PINDIR_INPUT)
{
source = FALSE;
@@ -1266,34 +1282,56 @@ static HRESULT WINAPI Mediacontrol_Run(I
while(IEnumPins_Next(pEnum, 1, &pPin, &dummy) == S_OK)
{
/* Explore the graph downstream from this pin */
- ExploreGraph(This, pPin, 0);
+ ExploreGraph(This, pPin, FoundFilter);
+ IPin_Release(pPin);
}
- IBaseFilter_Run(pfilter, 0);
+ FoundFilter(pfilter);
}
IEnumPins_Release(pEnum);
}
- This->state = State_Running;
+ return S_FALSE;
+}
+
+/*** IMediaControl methods ***/
+static HRESULT WINAPI Mediacontrol_Run(IMediaControl *iface) {
+ ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
+ TRACE("(%p/%p)->()\n", This, iface);
+
+ if (This->state == State_Running) return S_OK;
+ EnterCriticalSection(&This->cs);
+ SendTheFilterAMessage(iface, SendRun);
+ This->state = State_Running;
LeaveCriticalSection(&This->cs);
-
return S_FALSE;
}
static HRESULT WINAPI Mediacontrol_Pause(IMediaControl *iface) {
ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
+ TRACE("(%p/%p)->()\n", This, iface);
- TRACE("(%p/%p)->(): stub !!!\n", This, iface);
+ if (This->state == State_Paused) return S_OK;
- return S_OK;
+ EnterCriticalSection(&This->cs);
+ SendTheFilterAMessage(iface, SendPause);
+ This->state = State_Paused;
+ LeaveCriticalSection(&This->cs);
+ return S_FALSE;
}
static HRESULT WINAPI Mediacontrol_Stop(IMediaControl *iface) {
ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
+ TRACE("(%p/%p)->()\n", This, iface);
- TRACE("(%p/%p)->(): stub !!!\n", This, iface);
+ if (This->state == State_Stopped) return S_OK;
- return S_OK;
+ EnterCriticalSection(&This->cs);
+ if (This->state == State_Running) SendTheFilterAMessage(iface, SendPause);
+ SendTheFilterAMessage(iface, SendStop);
+ This->state = State_Stopped;
+ LeaveCriticalSection(&This->cs);
+ return S_FALSE;
}
static HRESULT WINAPI Mediacontrol_GetState(IMediaControl *iface,
-------------- next part --------------
Index: pin.c
===================================================================
RCS file: /home/wine/wine/dlls/quartz/pin.c,v
retrieving revision 1.13
diff -u -p -r1.13 pin.c
--- pin.c 2 Mar 2005 10:12:12 -0000 1.13
+++ pin.c 25 Apr 2005 15:45:29 -0000
@@ -49,7 +49,6 @@ static void Copy_PinInfo(PIN_INFO * pDes
strcpyW(pDest->achName, pSrc->achName);
pDest->dir = pSrc->dir;
pDest->pFilter = pSrc->pFilter;
- IBaseFilter_AddRef(pDest->pFilter);
}
/* Function called as a helper to IPin_Connect */
@@ -311,6 +314,7 @@ HRESULT WINAPI IPinImpl_QueryPinInfo(IPi
TRACE("(%p/%p)->(%p)\n", This, iface, pInfo);
Copy_PinInfo(pInfo, &This->pinInfo);
+ IBaseFilter_AddRef(pInfo->pFilter);
return S_OK;
}
-------------- next part --------------
Index: mediacatenum.c
===================================================================
RCS file: /home/wine/wine/dlls/devenum/mediacatenum.c,v
retrieving revision 1.14
diff -u -p -r1.14 mediacatenum.c
--- mediacatenum.c 10 Jan 2005 12:25:29 -0000 1.14
+++ mediacatenum.c 25 Apr 2005 15:52:01 -0000
@@ -434,6 +434,8 @@ static HRESULT WINAPI DEVENUM_IMediaCatM
res= IUnknown_QueryInterface(pObj,riidResult,ppvResult);
}
+ if (pmkToLeft == NULL && pObj != NULL) IUnknown_Release(pObj);
+
if (pProp)
{
IPropertyBag_Release(pProp);
More information about the wine-devel
mailing list