Suchen einer Schnittstelle für einen Filter oder eine Stecknadel
Bei vielen Vorgängen in DirectShow ruft die Anwendung Methoden im Filter-Graph Manager auf. In einigen Situationen muss die Anwendung jedoch eine Methode direkt auf einem Filter oder einer Stecknadel aufrufen. Beispielsweise machen viele Filter spezielle Schnittstellen verfügbar, die zum Konfigurieren des Filters verwendet werden.
Im Fall einer Filterschnittstelle verfügen Sie möglicherweise bereits über einen Zeiger auf die IBaseFilter-Schnittstelle des Filters. Verwenden Sie in diesem Fall einfach QueryInterface, um die andere Schnittstelle zu erhalten. Einige Filter können dem Diagramm jedoch vom Filter-Manager Graph werden. (Weitere Informationen finden Sie unter Intelligent Verbinden.) Verwenden Sie in diesem Fall die IEnumFilters-Schnittstelle, um eine Schleife durch alle Filter im Graphen zu erstellen, und fragen Sie jeden Filter nacheinander ab. Die folgende Funktion veranschaulicht dies:
HRESULT FindFilterInterface(
IGraphBuilder *pGraph, // Pointer to the Filter Graph Manager.
REFGUID iid, // IID of the interface to retrieve.
void **ppUnk) // Receives the interface pointer.
{
if (!pGraph || !ppUnk) return E_POINTER;
HRESULT hr = E_FAIL;
IEnumFilters *pEnum = NULL;
IBaseFilter *pF = NULL;
if (FAILED(pGraph->EnumFilters(&pEnum)))
{
return E_FAIL;
}
// Query every filter for the interface.
while (S_OK == pEnum->Next(1, &pF, 0))
{
hr = pF->QueryInterface(iid, ppUnk);
pF->Release();
if (SUCCEEDED(hr))
{
break;
}
}
pEnum->Release();
return hr;
}
Verwenden Sie die IEnumPins-Schnittstelle, um eine Schleife durch die Stecknadeln eines Filters zu erstellen, um eine Schnittstelle auf einem Pin zu finden. Die folgende Funktion zeigt, wie dies funktioniert:
HRESULT FindPinInterface(
IBaseFilter *pFilter, // Pointer to the filter to search.
REFGUID iid, // IID of the interface.
void **ppUnk) // Receives the interface pointer.
{
if (!pFilter || !ppUnk) return E_POINTER;
HRESULT hr = E_FAIL;
IEnumPins *pEnum = 0;
if (FAILED(pFilter->EnumPins(&pEnum)))
{
return E_FAIL;
}
// Query every pin for the interface.
IPin *pPin = 0;
while (S_OK == pEnum->Next(1, &pPin, 0))
{
hr = pPin->QueryInterface(iid, ppUnk);
pPin->Release();
if (SUCCEEDED(hr))
{
break;
}
}
pEnum->Release();
return hr;
}
Die nächste Funktion sucht nach einer Schnittstelle für einen Filter oder eine Stecknadel:
HRESULT FindInterfaceAnywhere(
IGraphBuilder *pGraph,
REFGUID iid,
void **ppUnk)
{
if (!pGraph || !ppUnk) return E_POINTER;
HRESULT hr = E_FAIL;
IEnumFilters *pEnum = 0;
if (FAILED(pGraph->EnumFilters(&pEnum)))
{
return E_FAIL;
}
// Loop through every filter in the graph.
IBaseFilter *pF = 0;
while (S_OK == pEnum->Next(1, &pF, 0))
{
hr = pF->QueryInterface(iid, ppUnk);
if (FAILED(hr))
{
// The filter does not expose the interface, but maybe
// one of its pins does.
hr = FindPinInterface(pF, iid, ppUnk);
}
pF->Release();
if (SUCCEEDED(hr))
{
break;
}
}
pEnum->Release();
return hr;
}
Beachten Sie, dass alle hier gezeigten Funktionen bei der ersten erfolgreichen QueryInterface-Funktion stehen bleiben.