Skip to content
Snippets Groups Projects
Commit 6301fec0 authored by Christian Costa's avatar Christian Costa Committed by Alexandre Julliard
Browse files

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.
parent cb0a4595
No related branches found
No related tags found
No related merge requests found
......@@ -352,13 +352,16 @@ static HRESULT WINAPI Graphbuilder_AddFilter(IGraphBuilder *iface,
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*));
LPWSTR * pNewNames = CoTaskMemAlloc(newCapacity * sizeof(LPWSTR));
memcpy(ppNewFilters, This->ppFiltersInGraph, This->nFilters * sizeof(IBaseFilter*));
memcpy(pNewNames, This->pFilterNames, This->nFilters * sizeof(LPWSTR));
CoTaskMemFree(This->ppFiltersInGraph);
CoTaskMemFree(This->pFilterNames);
if (!This->filterCapacity)
{
CoTaskMemFree(This->ppFiltersInGraph);
CoTaskMemFree(This->pFilterNames);
}
This->ppFiltersInGraph = ppNewFilters;
This->pFilterNames = pNewNames;
This->filterCapacity = newCapacity;
......@@ -461,6 +464,25 @@ static HRESULT WINAPI Graphbuilder_ConnectDirect(IGraphBuilder *iface,
/* 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);
if (SUCCEEDED(hr))
{
......@@ -623,9 +645,28 @@ static HRESULT WINAPI Graphbuilder_Connect(IGraphBuilder *iface,
ULONG nb;
IMoniker* pMoniker;
ULONG pin;
PIN_INFO PinInfo;
CLSID FilterCLSID;
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 */
hr = IPin_Connect(ppinOut, ppinIn, NULL);
if (SUCCEEDED(hr)) {
......@@ -633,6 +674,16 @@ static HRESULT WINAPI Graphbuilder_Connect(IGraphBuilder *iface,
}
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
* filter to the minor mediatype of input pin of the renderer */
hr = IPin_EnumMediaTypes(ppinOut, &penummt);
......@@ -674,14 +725,19 @@ static HRESULT WINAPI Graphbuilder_Connect(IGraphBuilder *iface,
hr = GetFilterInfo(pMoniker, &clsid, &var);
IMoniker_Release(pMoniker);
if (FAILED(hr)) {
ERR("Unable to retrieve filter info (%lx)\n", hr);
goto error;
ERR("Unable to retrieve filter info (%lx)\n", hr);
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);
if (FAILED(hr)) {
ERR("Unable to create filter (%lx), trying next one\n", hr);
goto error;
ERR("Unable to create filter (%lx), trying next one\n", hr);
goto error;
}
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);
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);
if (FAILED(hr)) {
ERR("EnumMediaTypes (%lx)\n", hr);
......@@ -819,7 +887,6 @@ static HRESULT WINAPI Graphbuilder_Render(IGraphBuilder *iface,
hr = IGraphBuilder_AddFilter(iface, pfilter, NULL);
if (FAILED(hr)) {
ERR("Unable to add filter (%lx)\n", hr);
IBaseFilter_Release(pfilter);
pfilter = NULL;
goto error;
}
......@@ -1295,7 +1362,7 @@ static HRESULT SendFilterMessage(IMediaControl *iface, fnFoundFilter FoundFilter
}
if (source == TRUE)
{
TRACE("Found a source filter\n");
TRACE("Found a source filter %p\n", pfilter);
IEnumPins_Reset(pEnum);
while(IEnumPins_Next(pEnum, 1, &pPin, &dummy) == S_OK)
{
......@@ -1364,7 +1431,7 @@ static HRESULT WINAPI Mediacontrol_GetState(IMediaControl *iface,
*pfs = This->state;
LeaveCriticalSection(&This->cs);
return S_OK;
}
......
......@@ -201,7 +201,7 @@ HRESULT TransformFilter_Create(TransformFilterImpl* pTransformFilter, const CLSI
piOutput.pFilter = (IBaseFilter *)pTransformFilter;
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))
{
......@@ -211,7 +211,7 @@ HRESULT TransformFilter_Create(TransformFilterImpl* pTransformFilter, const CLSI
props.cbBuffer = 0; /* Will be updated at connection time */
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))
ERR("Cannot create output pin (%lx)\n", hr);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment