|This is retired content. This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This content may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.|
Before two filters can be connected, they must each be added to the filter graph. When building a filter graph using Intelligent Connect (such as within a call to IMediaControl::RenderFile), the filter graph manager adds filters to the graph based on the media type in the file it has been given to render. The Graph Builder objects build specific types of graphs by selecting a predetermined configuration of filters. An application can also build a graph manually by instructing the filter graph manager to add specific filters. In any of these scenarios, the filter is added to the graph by the IFilterGraph::AddFiltermethod, and the filter is notified that it has joined the graph by a call to the IBaseFilter::JoinFilterGraphmethod. The added filter can then be connected to the filter(s) upstream and/or downstream from it. To initiate the connection process, the filter graph manager requests the filters to enumerate their pins and then, for each connection required, requests that an output pin connect to an input_pin by calling the output pin's IPin::Connectmethod. All the details of the connection are then negotiated by the two pins within the scope of Connect.
To say that two filters are "connected" means that they have agreed on the media type of the data that will pass between them, and the size and location of the shared data buffers. The connection type is closely related to the transport type. There are different types of transport depending on whether the data is being "pushed" or "pulled" and whether the data buffers are located in main memory or on a hardware device.
The connection/tranport type discussed here is an IMemInputPin connection, in which the buffers are allocated from main memory and the data is "pushed" into the buffer from the upstream pin. The base classes handle much of this connection mechanism. However, it is important to understand the connection process when writing a filter so that you can identify what to override and what is expected of your filter. Before two connected filters are prepared to pass media between them, the following connection and negotiation processes must occur in this order.
In the first step, the filter graph manager informs the output pin of the upstream filter to connect to a specified input pin of the downstream filter. This results in an exchange of IPininterface pointers. Filters should never connect to other filters by themselves. The filter graph manager must always be the agent that initiates a connection, because deadlocks can occur otherwise. A filter or an application can instruct the filter graph manager to connect two pins (through the IGraphBuilder::Connector IFilterGraph::ConnectDirectmethod), or the filter graph manager can determine to connect filters when rendering a filter by using the IGraphBuilder::Renderor IGraphBuilder::RenderFilemethod.
In the second step, the output pin may request the IMemInputPininterface from the connected input pin. This is in preparation for the fourth step, where the output pin will use IMemInputPinto retrieve a memory allocator from the input pin. If the output pin already has a memory allocator (or some other transport in the case of hardware filters), it can skip this step or can request some other interface in a proprietary design.
In the third step, media types are tried until one is found that is acceptable to both pins or the pins run out of types to try (in which case the connection fails). First, the output pin asks the connected input pin to propose its list of media types. If none of these are acceptable to the output pin, the output pin proposes its own types.
In the fourth step, the output pin asks the connected input pin for an interface to a memory allocator object. In the base classes, these objects are implemented by CBaseAllocator and CMemAllocator. These objects create the media samples and their associated data buffers that each pin will access in order to transfer the multimedia data. If the output pin does not accept the input pin's allocator (for reasons discussed below), it can propose its own allocator. In either case it must notify the input pin of the selection.
Last updated on Tuesday, May 18, 2004