Partager via


Rechercher une épingle non connectée sur un filtre

[La fonctionnalité associée à cette page, DirectShow, est une fonctionnalité héritée. Il a été remplacé par MediaPlayer, IMFMediaEngine et Audio/Video Capture dans Media Foundation. Ces fonctionnalités ont été optimisées pour Windows 10 et Windows 11. Microsoft recommande vivement au nouveau code d’utiliser MediaPlayer, IMFMediaEngine et La capture audio/vidéo dans Media Foundation au lieu de DirectShow, lorsque cela est possible. Microsoft suggère que le code existant qui utilise les API héritées soit réécrit pour utiliser les nouvelles API si possible.]

Cette rubrique explique comment rechercher une épingle non connectée sur un filtre. La recherche d’une broche non connectée est utile lorsque vous connectez des filtres.

Dans un scénario de création de graphiques DirectShow classique, vous avez besoin d’une broche non connectée qui correspond à une direction de broche particulière (entrée ou sortie). Par exemple, lorsque vous connectez deux filtres, vous connectez une broche de sortie d’un filtre à une broche d’entrée de l’autre filtre. Les deux broches doivent être déconnectées avant de les connecter.

Tout d’abord, nous avons besoin d’une fonction qui teste si une broche est connectée à une autre broche. Cette fonction appelle la méthode IPin::ConnectedTo pour tester si la broche est connectée à une autre broche.

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

Notes

Cet exemple utilise la fonction SafeRelease pour libérer les pointeurs d’interface.

 

Ensuite, nous avons besoin d’une fonction qui teste si une broche correspond à une direction de broche spécifiée. Cette fonction appelle la méthode IPin::QueryDirection pour obtenir le sens de la broche.

// 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 fonction suivante correspond à une broche par les deux critères (direction et status de connexion).

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

Enfin, la fonction suivante utilise l’interface IEnumPins pour parcourir les broches du filtre. L’appelant spécifie la direction de broche souhaitée. Pour chaque broche, la fonction appelle MatchPin pour tester si la broche est une correspondance. Si la direction correspond et que la broche n’est pas connectée, la fonction retourne un pointeur vers l’épingle correspondante dans le paramètre 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;
}

Pour obtenir un exemple d’utilisation de cette fonction, consultez Connecter deux filtres.

Énumération de broches

Techniques de Graph-Building générales

ICaptureGraphBuilder2::FindPin