Working with Pin Categories
A version of this page is also available for
4/8/2010
To search on a filter for a pin with a given pin category, you can use the ICaptureGraphBuilder2::FindPin method. The following code searches for a video preview pin:
int i = 0;
hr = pBuild->FindPin(
pFilter, // Pointer to a filter to search.
PINDIR_OUTPUT, // Which pin direction?
&PIN_CATEGORY_PREVIEW, // Which category? (NULL means "any category")
&MEDIATYPE_Video, // What media type? (NULL means "any type")
FALSE, // Must be connected?
i, // Get the i'th matching pin (0 = first match)
&pPin // Receives a pointer to the pin.
);
The first parameter is a pointer to the filter's IBaseFilter Interface. The next three parameters specify the direction, pin category, and media type. The value FALSE in the fifth parameter indicates that the pin can be either connected or unconnected. (For the exact definitions of these parameters, refer to the documentation for the method.) If the method finds a matching pin, it returns a pointer to the IPin Interface in the pPin parameter.
Although the ICaptureGraphBuilder2::FindPin method is convenient, you can also write your own helper functions if you prefer. To determine a pin's category, call the IKsPropertySet::Set method as described in the topic Pin Property Set.
The following code shows a helper function that checks whether a pin matches a specified category:
BOOL PinMatchesCategory(IPin *pPin, const GUID& Category)
{
if (pPin == NULL) return E_POINTER;
BOOL bFound = FALSE;
IKsPropertySet *pKs;
HRESULT hr = pPin->QueryInterface(IID_IKsPropertySet, (void **)&pKs);
if (SUCCEEDED(hr))
{
GUID PinCategory;
DWORD cbReturned;
hr = pKs->Get(AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY, NULL, 0,
&PinCategory, sizeof(GUID), &cbReturned);
if (SUCCEEDED(hr))
{
bFound = (PinCategory == Category);
}
pKs->Release();
}
return bFound;
}
The next example is a function that searches for a pin by category, similar to the ICaptureGraphBuilder2::FindPin method:
HRESULT FindPinByCategory(
IBaseFilter *pF, // Pointer to the filter to search.
PIN_DIRECTION PinDir, // Direction of the pin.
const GUID& Category, // Pin category.
IPin **ppPin) // Receives a pointer to the pin.
{
if (!pF || !ppPin) return E_POINTER;
*ppPin = 0;
HRESULT hr;
IEnumPins *pEnum = 0;
if (SUCCEEDED(pF->EnumPins(&pEnum)))
{
IPin *pPin = 0;
while (hr = pEnum->Next(1, &pPin, 0), hr == S_OK)
{
PIN_DIRECTION ThisPinDir;
hr = pPin->QueryDirection(&ThisPinDir);
if (FAILED(hr))
{
pPin->Release();
pEnum->Release();
return E_UNEXPECTED; // Something strange happened.
}
if ((ThisPinDir == PinDir) &&
PinMatchesCategory(pPin, Category))
{
*ppPin = pPin; // Caller must release the interface.
pEnum->Release();
return S_OK;
}
pPin->Release();
}
pEnum->Release();
}
// No pin matches.
return E_FAIL;
}
The following code uses the previous function to search for a still image pin on a filter:
IPin *pVP;
hr = FindPinByCategory(pFilter, PINDIR_OUTPUT,
PIN_CATEGORY_STILL, &pVP);
if (SUCCEEDED(hr))
{
// Use pVP ...
// Release when you are done.
pVP->Release();
}