Properly allocate/release memory when adding filters to the filtergraph.

When connecting pin, discard filter which is the same as the upstream
one.
Remove wrong extra IBaseFilter_Release.
Improve traces by showing filters owing pins we want to connect or
render.
Properly initialize output pin of transform filter.
This commit is contained in:
Christian Costa 2005-08-22 09:21:24 +00:00 committed by Alexandre Julliard
parent cb0a4595ba
commit 6301fec0ef
2 changed files with 79 additions and 12 deletions

View File

@ -352,13 +352,16 @@ static HRESULT WINAPI Graphbuilder_AddFilter(IGraphBuilder *iface,
if (This->nFilters + 1 > This->filterCapacity) if (This->nFilters + 1 > This->filterCapacity)
{ {
int newCapacity = 2*This->filterCapacity; int newCapacity = This->filterCapacity ? 2 * This->filterCapacity : 1;
IBaseFilter ** ppNewFilters = CoTaskMemAlloc(newCapacity * sizeof(IBaseFilter*)); IBaseFilter ** ppNewFilters = CoTaskMemAlloc(newCapacity * sizeof(IBaseFilter*));
LPWSTR * pNewNames = CoTaskMemAlloc(newCapacity * sizeof(LPWSTR)); LPWSTR * pNewNames = CoTaskMemAlloc(newCapacity * sizeof(LPWSTR));
memcpy(ppNewFilters, This->ppFiltersInGraph, This->nFilters * sizeof(IBaseFilter*)); memcpy(ppNewFilters, This->ppFiltersInGraph, This->nFilters * sizeof(IBaseFilter*));
memcpy(pNewNames, This->pFilterNames, This->nFilters * sizeof(LPWSTR)); memcpy(pNewNames, This->pFilterNames, This->nFilters * sizeof(LPWSTR));
CoTaskMemFree(This->ppFiltersInGraph); if (!This->filterCapacity)
CoTaskMemFree(This->pFilterNames); {
CoTaskMemFree(This->ppFiltersInGraph);
CoTaskMemFree(This->pFilterNames);
}
This->ppFiltersInGraph = ppNewFilters; This->ppFiltersInGraph = ppNewFilters;
This->pFilterNames = pNewNames; This->pFilterNames = pNewNames;
This->filterCapacity = newCapacity; This->filterCapacity = newCapacity;
@ -461,6 +464,25 @@ static HRESULT WINAPI Graphbuilder_ConnectDirect(IGraphBuilder *iface,
/* FIXME: check pins are in graph */ /* FIXME: check pins are in graph */
if (TRACE_ON(quartz))
{
PIN_INFO PinInfo;
hr = IPin_QueryPinInfo(ppinIn, &PinInfo);
if (FAILED(hr))
return hr;
TRACE("Filter owning first pin => %p\n", PinInfo.pFilter);
IBaseFilter_Release(PinInfo.pFilter);
hr = IPin_QueryPinInfo(ppinOut, &PinInfo);
if (FAILED(hr))
return hr;
TRACE("Filter owning second pin => %p\n", PinInfo.pFilter);
IBaseFilter_Release(PinInfo.pFilter);
}
hr = IPin_QueryDirection(ppinIn, &dir); hr = IPin_QueryDirection(ppinIn, &dir);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
@ -623,9 +645,28 @@ static HRESULT WINAPI Graphbuilder_Connect(IGraphBuilder *iface,
ULONG nb; ULONG nb;
IMoniker* pMoniker; IMoniker* pMoniker;
ULONG pin; ULONG pin;
PIN_INFO PinInfo;
CLSID FilterCLSID;
TRACE("(%p/%p)->(%p, %p)\n", This, iface, ppinOut, ppinIn); TRACE("(%p/%p)->(%p, %p)\n", This, iface, ppinOut, ppinIn);
if (TRACE_ON(quartz))
{
hr = IPin_QueryPinInfo(ppinIn, &PinInfo);
if (FAILED(hr))
return hr;
TRACE("Filter owning first pin => %p\n", PinInfo.pFilter);
IBaseFilter_Release(PinInfo.pFilter);
hr = IPin_QueryPinInfo(ppinOut, &PinInfo);
if (FAILED(hr))
return hr;
TRACE("Filter owning second pin => %p\n", PinInfo.pFilter);
IBaseFilter_Release(PinInfo.pFilter);
}
/* Try direct connection first */ /* Try direct connection first */
hr = IPin_Connect(ppinOut, ppinIn, NULL); hr = IPin_Connect(ppinOut, ppinIn, NULL);
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
@ -633,6 +674,16 @@ static HRESULT WINAPI Graphbuilder_Connect(IGraphBuilder *iface,
} }
TRACE("Direct connection failed, trying to insert other filters\n"); TRACE("Direct connection failed, trying to insert other filters\n");
hr = IPin_QueryPinInfo(ppinIn, &PinInfo);
if (FAILED(hr))
return hr;
hr = IBaseFilter_GetClassID(PinInfo.pFilter, &FilterCLSID);
if (FAILED(hr))
return hr;
IBaseFilter_Release(PinInfo.pFilter);
/* Find the appropriate transform filter than can transform the minor media type of output pin of the upstream /* Find the appropriate transform filter than can transform the minor media type of output pin of the upstream
* filter to the minor mediatype of input pin of the renderer */ * filter to the minor mediatype of input pin of the renderer */
hr = IPin_EnumMediaTypes(ppinOut, &penummt); hr = IPin_EnumMediaTypes(ppinOut, &penummt);
@ -674,14 +725,19 @@ static HRESULT WINAPI Graphbuilder_Connect(IGraphBuilder *iface,
hr = GetFilterInfo(pMoniker, &clsid, &var); hr = GetFilterInfo(pMoniker, &clsid, &var);
IMoniker_Release(pMoniker); IMoniker_Release(pMoniker);
if (FAILED(hr)) { if (FAILED(hr)) {
ERR("Unable to retrieve filter info (%lx)\n", hr); ERR("Unable to retrieve filter info (%lx)\n", hr);
goto error; goto error;
}
if (IsEqualGUID(&clsid, &FilterCLSID)) {
/* Skip filter (same as the one the output pin belongs to) */
goto error;
} }
hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (LPVOID*)&pfilter); hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (LPVOID*)&pfilter);
if (FAILED(hr)) { if (FAILED(hr)) {
ERR("Unable to create filter (%lx), trying next one\n", hr); ERR("Unable to create filter (%lx), trying next one\n", hr);
goto error; goto error;
} }
hr = IGraphBuilder_AddFilter(iface, pfilter, NULL); hr = IGraphBuilder_AddFilter(iface, pfilter, NULL);
@ -767,6 +823,18 @@ static HRESULT WINAPI Graphbuilder_Render(IGraphBuilder *iface,
TRACE("(%p/%p)->(%p)\n", This, iface, ppinOut); TRACE("(%p/%p)->(%p)\n", This, iface, ppinOut);
if (TRACE_ON(quartz))
{
PIN_INFO PinInfo;
hr = IPin_QueryPinInfo(ppinOut, &PinInfo);
if (FAILED(hr))
return hr;
TRACE("Filter owning pin => %p\n", PinInfo.pFilter);
IBaseFilter_Release(PinInfo.pFilter);
}
hr = IPin_EnumMediaTypes(ppinOut, &penummt); hr = IPin_EnumMediaTypes(ppinOut, &penummt);
if (FAILED(hr)) { if (FAILED(hr)) {
ERR("EnumMediaTypes (%lx)\n", hr); ERR("EnumMediaTypes (%lx)\n", hr);
@ -819,7 +887,6 @@ static HRESULT WINAPI Graphbuilder_Render(IGraphBuilder *iface,
hr = IGraphBuilder_AddFilter(iface, pfilter, NULL); hr = IGraphBuilder_AddFilter(iface, pfilter, NULL);
if (FAILED(hr)) { if (FAILED(hr)) {
ERR("Unable to add filter (%lx)\n", hr); ERR("Unable to add filter (%lx)\n", hr);
IBaseFilter_Release(pfilter);
pfilter = NULL; pfilter = NULL;
goto error; goto error;
} }
@ -1295,7 +1362,7 @@ static HRESULT SendFilterMessage(IMediaControl *iface, fnFoundFilter FoundFilter
} }
if (source == TRUE) if (source == TRUE)
{ {
TRACE("Found a source filter\n"); TRACE("Found a source filter %p\n", pfilter);
IEnumPins_Reset(pEnum); IEnumPins_Reset(pEnum);
while(IEnumPins_Next(pEnum, 1, &pPin, &dummy) == S_OK) while(IEnumPins_Next(pEnum, 1, &pPin, &dummy) == S_OK)
{ {
@ -1364,7 +1431,7 @@ static HRESULT WINAPI Mediacontrol_GetState(IMediaControl *iface,
*pfs = This->state; *pfs = This->state;
LeaveCriticalSection(&This->cs); LeaveCriticalSection(&This->cs);
return S_OK; return S_OK;
} }

View File

@ -201,7 +201,7 @@ HRESULT TransformFilter_Create(TransformFilterImpl* pTransformFilter, const CLSI
piOutput.pFilter = (IBaseFilter *)pTransformFilter; piOutput.pFilter = (IBaseFilter *)pTransformFilter;
lstrcpynW(piOutput.achName, wcsOutputPinName, sizeof(piOutput.achName) / sizeof(piOutput.achName[0])); lstrcpynW(piOutput.achName, wcsOutputPinName, sizeof(piOutput.achName) / sizeof(piOutput.achName[0]));
hr = TransformFilter_InputPin_Construct(&piInput, TransformFilter_Sample, (LPVOID)pTransformFilter, TransformFilter_Input_QueryAccept, &pTransformFilter->csFilter, &pTransformFilter->ppPins[0]); hr = TransformFilter_InputPin_Construct(&piInput, TransformFilter_Sample, pTransformFilter, TransformFilter_Input_QueryAccept, &pTransformFilter->csFilter, &pTransformFilter->ppPins[0]);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
@ -211,7 +211,7 @@ HRESULT TransformFilter_Create(TransformFilterImpl* pTransformFilter, const CLSI
props.cbBuffer = 0; /* Will be updated at connection time */ props.cbBuffer = 0; /* Will be updated at connection time */
props.cBuffers = 2; props.cBuffers = 2;
hr = TransformFilter_OutputPin_Construct(&piOutput, &props, NULL, TransformFilter_Output_QueryAccept, &pTransformFilter->csFilter, &pTransformFilter->ppPins[1]); hr = TransformFilter_OutputPin_Construct(&piOutput, &props, pTransformFilter, TransformFilter_Output_QueryAccept, &pTransformFilter->csFilter, &pTransformFilter->ppPins[1]);
if (FAILED(hr)) if (FAILED(hr))
ERR("Cannot create output pin (%lx)\n", hr); ERR("Cannot create output pin (%lx)\n", hr);