Microsoft DirectX 8.0

Enumerating Objects in a Filter Graph

Most of the time, you don't have to worry about individual filters and pins, because a Microsoft® DirectShow® application can simply call methods on the filter graph. Occasionally, however, you will need to locate a particular filter in the graph or even a particular pin on a filter. For example, your application might use a custom interface that a filter exposes, in order to set properties on the filter. Or, you might construct a specialized filter graph by hand and need to call methods on individual pins to connect the filters. For this purpose, DirectShow provides several methods for enumerating objects in a filter graph.

The enumerators discussed in this section follow the standard form used by COM enumeration interfaces. For more information, see the IEnumXXXX topic in the Platform SDK. For information on enumerating filters that are registered on the user's computer, but aren't yet in the filter graph, see Enumerating Devices and Filters.

This article contains the following topics:

Enumerating Filters

The filter graph manager supports the IFilterGraph::EnumFilters method, which enumerates all the filters in the filter graph. It returns a pointer to the IEnumFilters interface. The IEnumFilters::Next method retrieves IBaseFilter interface pointers.

The following example shows a function that enumerates the filters in a graph and displays a message box with each filter's name. It uses the IBaseFilter::QueryFilterInfo method to retrieve the name of the filter. Note the places where the function calls IUnknown::Release on an interface to decrement the reference count.

void EnumFilters (IFilterGraph *pGraph) 
{
    IEnumFilters *pEnum = NULL;
    IBaseFilter *pFilter;
    ULONG cFetched;

    pGraph->EnumFilters(&pEnum);
    while(pEnum->Next(1, &pFilter, &cFetched) == S_OK)
    {
        FILTER_INFO FilterInfo;
        char szName[256];
        
        pFilter->QueryFilterInfo(&FilterInfo);
        WideCharToMultiByte(CP_ACP, 0, FilterInfo.achName, -1, szName, 256, 0, 0);
        MessageBox(NULL, szName, "Filter name", MB_OK);

        FilterInfo.pGraph->Release();
        pFilter->Release();
    }
    pEnum->Release();
}

Enumerating Pins

Filters support the IBaseFilter::EnumPins method, which enumerates the pins available on the filter. It returns a pointer to the IEnumPins interface. The IEnumPins::Next method retrieves IPin interface pointers.

The following example shows a function that locates a pin with a given direction (input or output) on a given filter. It uses the PIN_DIRECTION enumeration to specify the pin direction, and the IPin::QueryDirection method to find the direction of each enumerated pin. If this function finds a matching pin, it returns an IPin interface pointer with an outstanding reference count. The caller is responsible for releasing the interface.

IPin *GetPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir)
{
    BOOL       bFound = FALSE;
    IEnumPins  *pEnum;
    IPin       *pPin;

    pFilter->EnumPins(&pEnum);
    while(pEnum->Next(1, &pPin, 0) == S_OK)
    {
        PIN_DIRECTION PinDirThis;
        pPin->QueryDirection(&PinDirThis);
        if (bFound = (PinDir == PinDirThis))
            break;
        pPin->Release();
    }
    pEnum->Release();
    return (bFound ? pPin : 0);  
}

Enumerating Media Types

Pins support the IPin::EnumMediaTypes method, which enumerates a pin's preferred media types. It returns a pointer to the IEnumMediaTypes interface. The IEnumMediaTypes::Next method retrieves pointers to AM_MEDIA_TYPE structures describing media types.

The media type enumerator exists primarily to help the filter graph make intelligent connections, and your applications will probably not use it. A pin does not necessarily return any preferred media types. Moreover, the media types it returns might depend on the filter's connection status. For example, a filter's output pin might return a different set of media types depending on which media type was set for the filter's input pin.