Trovare un'interfaccia in un filtro o un pin

[La funzionalità associata a questa pagina, DirectShow, è una funzionalità legacy. È stata sostituita da MediaPlayer, IMFMediaEngine e Audio/Video Capture in Media Foundation. Queste funzionalità sono state ottimizzate per Windows 10 e Windows 11. Microsoft consiglia vivamente che il nuovo codice usi MediaPlayer, IMFMediaEngine e Audio/Video Capture in Media Foundation invece di DirectShow, quando possibile. Microsoft suggerisce che il codice esistente che usa le API legacy venga riscritto per usare le nuove API, se possibile.

Per molte operazioni in DirectShow, l'applicazione chiama i metodi in Filter Graph Manager. In alcune situazioni, tuttavia, l'applicazione deve chiamare un metodo direttamente su un filtro o un pin. Ad esempio, molti filtri espongono interfacce specializzate usate per configurare il filtro.

Nel caso di un'interfaccia di filtro, potrebbe essere già presente un puntatore all'interfaccia IBaseFilter del filtro. In questo caso, usare semplicemente QueryInterface per ottenere l'altra interfaccia. Tuttavia, alcuni filtri potrebbero essere aggiunti al grafico da Filter Graph Manager. Per informazioni dettagliate, vedere Intelligent Connect. In tal caso, usare l'interfaccia IEnumFilters per scorrere tutti i filtri nel grafico ed eseguire una query a ogni turno. La funzione seguente illustra quanto segue:

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;
}

Per trovare un'interfaccia su un pin, usare l'interfaccia IEnumPins per scorrere i pin in un filtro. La funzione seguente illustra come eseguire questa operazione:

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;
}

La funzione successiva cerca un'interfaccia in un filtro o un pin:

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;
}

Si noti che tutte le funzioni mostrate qui si arrestano al primo queryInterface riuscito.

Enumerazione dei filtri

Enumerazione dei pin

ICaptureGraphBuilder2::FindInterface