Find an Unconnected Pin on a Filter

This topic describes how to find an unconnected pin on a filter. Finding an unconnected pin is useful when you are connecting filters.

In a typical DirectShow graph-building scenario, you need an unconnected pin that matches a particular pin direction (input or output). For example, when you connect two filters, you connect an output pin from one filter to an input pin from the other filter. Both pins must be unconnected before you connect them.

First, we need a function that tests whether a pin is connected to another pin. This function calls the IPin::ConnectedTo method to test whether the pin is connected to another 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;
}


Note  This example uses the SafeRelease function to release interface pointers.
 

Next, we need a function that tests whether a pin matches a specified pin direction. This function calls the IPin::QueryDirection method to get the pin direction.


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


The next function matches a pin by both criteria (pin direction and connection 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;
}


Finally, the following function uses the IEnumPins interface to loop through the pins on the filter. The caller specifies the desired pin direction. For each pin, the function calls MatchPin to test whether the pin is a match. If the direction matches and the pin is unconnected, the function returns a pointer to the matching pin in the ppPin parameter.



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


For an example of how this function can be used, see Connect Two Filters.

Related topics

Enumerating Pins
General Graph-Building Techniques
ICaptureGraphBuilder2::FindPin

 

 

Show: