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)
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue