Trovare un pin non connesso in un filtro

[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.

In questo argomento viene descritto come trovare un pin non connesso in un filtro. La ricerca di un pin non connesso è utile quando si connettono filtri.

In uno scenario tipico di compilazione del grafo DirectShow, è necessario un pin non connesso che corrisponda a una particolare direzione del pin (input o output). Ad esempio, quando si connettono due filtri, si connette un pin di output da un filtro a un pin di input dall'altro filtro. Entrambi i pin devono essere scollegati prima di connetterli.

Prima di tutto, è necessaria una funzione che verifica se un pin è connesso a un altro pin. Questa funzione chiama il metodo IPin::ConnectedTo per verificare se il pin è connesso a un altro pin.

// Query whether a pin is connected to another pin.
//
// Note: This function does not return a pointer to the connected pin.

HRESULT IsPinConnected(IPin *pPin, BOOL *pResult)
{
    IPin *pTmp = NULL;
    HRESULT hr = pPin->ConnectedTo(&pTmp);
    if (SUCCEEDED(hr))
    {
        *pResult = TRUE;
    }
    else if (hr == VFW_E_NOT_CONNECTED)
    {
        // The pin is not connected. This is not an error for our purposes.
        *pResult = FALSE;
        hr = S_OK;
    }

    SafeRelease(&pTmp);
    return hr;
}

Nota

In questo esempio viene usata la funzione SafeRelease per rilasciare puntatori all'interfaccia.

 

Successivamente, è necessaria una funzione che verifica se un pin corrisponde a una direzione del pin specificata. Questa funzione chiama il metodo IPin::QueryDirection per ottenere la direzione del pin.

// Query whether a pin has a specified direction (input / output)
HRESULT IsPinDirection(IPin *pPin, PIN_DIRECTION dir, BOOL *pResult)
{
    PIN_DIRECTION pinDir;
    HRESULT hr = pPin->QueryDirection(&pinDir);
    if (SUCCEEDED(hr))
    {
        *pResult = (pinDir == dir);
    }
    return hr;
}

La funzione successiva corrisponde a un pin in base a entrambi i criteri (direzione del pin e stato della connessione).

// Match a pin by pin direction and connection state.
HRESULT MatchPin(IPin *pPin, PIN_DIRECTION direction, BOOL bShouldBeConnected, BOOL *pResult)
{
    assert(pResult != NULL);

    BOOL bMatch = FALSE;
    BOOL bIsConnected = FALSE;

    HRESULT hr = IsPinConnected(pPin, &bIsConnected);
    if (SUCCEEDED(hr))
    {
        if (bIsConnected == bShouldBeConnected)
        {
            hr = IsPinDirection(pPin, direction, &bMatch);
        }
    }

    if (SUCCEEDED(hr))
    {
        *pResult = bMatch;
    }
    return hr;
}

Infine, la funzione seguente usa l'interfaccia IEnumPins per scorrere i pin nel filtro. Il chiamante specifica la direzione del segnaposto desiderata. Per ogni pin, la funzione chiama MatchPin per verificare se il pin è una corrispondenza. Se la direzione corrisponde e il pin non è connesso, la funzione restituisce un puntatore al pin corrispondente nel parametro ppPin .

// Return the first unconnected input pin or output pin.
HRESULT FindUnconnectedPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir, IPin **ppPin)
{
    IEnumPins *pEnum = NULL;
    IPin *pPin = NULL;
    BOOL bFound = FALSE;

    HRESULT hr = pFilter->EnumPins(&pEnum);
    if (FAILED(hr))
    {
        goto done;
    }

    while (S_OK == pEnum->Next(1, &pPin, NULL))
    {
        hr = MatchPin(pPin, PinDir, FALSE, &bFound);
        if (FAILED(hr))
        {
            goto done;
        }
        if (bFound)
        {
            *ppPin = pPin;
            (*ppPin)->AddRef();
            break;
        }
        SafeRelease(&pPin);
    }

    if (!bFound)
    {
        hr = VFW_E_NOT_FOUND;
    }

done:
    SafeRelease(&pPin);
    SafeRelease(&pEnum);
    return hr;
}

Per un esempio di come questa funzione può essere usata, vedere Connettere due filtri.

Enumerazione dei pin

Tecniche di Graph-Building generali

ICaptureGraphBuilder2::FindPin