Freigeben über


Suchen einer nicht verbundenen Pin in einem Filter

[Das dieser Seite zugeordnete Feature DirectShow ist ein Legacyfeature. Es wurde von MediaPlayer, IMFMediaEngine und Audio/Video Capture in Media Foundation abgelöst. Diese Features wurden für Windows 10 und Windows 11 optimiert. Microsoft empfiehlt dringend, dass neuer Code mediaPlayer, IMFMediaEngine und Audio/Video Capture in Media Foundation anstelle von DirectShow verwendet, wenn möglich. Microsoft schlägt vor, dass vorhandener Code, der die Legacy-APIs verwendet, so umgeschrieben wird, dass nach Möglichkeit die neuen APIs verwendet werden.]

In diesem Thema wird beschrieben, wie Sie einen nicht verbundenen Pin in einem Filter finden. Die Suche nach einem nicht verbundenen Pin ist nützlich, wenn Sie Filter verbinden.

In einem typischen DirectShow-Diagrammerstellungsszenario benötigen Sie einen nicht verbundenen Pin, der einer bestimmten Pinrichtung (Eingabe oder Ausgabe) entspricht. Wenn Sie beispielsweise zwei Filter verbinden, verbinden Sie einen Ausgabepin von einem Filter mit einem Eingabestift des anderen Filters. Beide Pins müssen nicht verbunden sein, bevor Sie sie verbinden.

Zunächst benötigen wir eine Funktion, die testet, ob ein Pin mit einem anderen Pin verbunden ist. Diese Funktion ruft die IPin::ConnectedTo-Methode auf, um zu testen, ob der Pin mit einem anderen Pin verbunden ist.

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

Hinweis

In diesem Beispiel wird die SafeRelease-Funktion verwendet, um Schnittstellenzeiger freizugeben.

 

Als Nächstes benötigen wir eine Funktion, die testet, ob ein Pin mit einer angegebenen Pinrichtung übereinstimmt. Diese Funktion ruft die IPin::QueryDirection-Methode auf, um die Pinrichtung abzurufen.

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

Die nächste Funktion entspricht einem Pin nach beiden Kriterien (Pinrichtung und Verbindung status).

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

Schließlich verwendet die folgende Funktion die IEnumPins-Schnittstelle , um die Pins im Filter zu durchlaufen. Der Aufrufer gibt die gewünschte Pinrichtung an. Für jeden Pin ruft die Funktion auf MatchPin , um zu testen, ob der Pin eine Übereinstimmung ist. Wenn die Richtung übereinstimmt und der Pin nicht verbunden ist, gibt die Funktion einen Zeiger auf den entsprechenden Stift im ppPin-Parameter zurück.

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

Ein Beispiel für die Verwendung dieser Funktion finden Sie unter Verbinden von zwei Filtern.

Aufzählen von Pins

Allgemeine Graph-Building Techniken

ICaptureGraphBuilder2::FindPin