Find an Unconnected Pin on a Filter
[The feature associated with this page, DirectShow, is a legacy feature. It has been superseded by MediaPlayer, IMFMediaEngine, and Audio/Video Capture in Media Foundation. Those features have been optimized for Windows 10 and Windows 11. Microsoft strongly recommends that new code use MediaPlayer, IMFMediaEngine and Audio/Video Capture in Media Foundation instead of DirectShow, when possible. Microsoft suggests that existing code that uses the legacy APIs be rewritten to use the new APIs if possible.]
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