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:
parent
cb0a4595ba
commit
6301fec0ef
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue