Microsoft DirectX 8.0 |
This article describes how filters connect in Microsoft® DirectShow®. The article is intended for filter developers. If you are writing a DirectShow application, you can probably ignore the details presented here.
This article contains the following topics:
Filters connect at their pins, through the IPin interface. Output pins connect to input pins. Each pin connection has a media type, described by the AM_MEDIA_TYPE structure.
An application connects filters by calling methods on the filter graph manager, never by calling methods on the filters or pins themselves. The application can directly specify the filters to connect, by calling the IFilterGraph::ConnectDirect or IGraphBuilder::Connect method. Or it can connect filters indirectly with one of the graph-building methods, such as IGraphBuilder::RenderFile.
For the connection to succeed, both filters must be in the filter graph. The application can add a filter to the graph by calling the IFilterGraph::AddFilter method. The filter graph manager can also create filters add them to the graph. In either case, the filter graph manager calls the filter's IBaseFilter::JoinFilterGraph method to notify the filter.
The general outline of the connection process is the following:
Some pins can be disconnected and reconnected while the filter is active. This type of reconnection is called a dynamic reconnection. For more information, see Dynamic Graph Building. However, most filters do not support dynamic reconnection.
Filters are usually connected in downstream orderin other words, the filter's input pins are connected before its output pins. A filter should always support this order of connection. Some filters also support connections in the opposite orderoutput pins first, followed by input pins. For example, it might be possible to connect a MUX filter's output pin to a file-writer filter, before connecting the MUX filter's input pins.
When the filter graph manager calls the IPin::Connect method, it has several options for specifying a media type:
If the pins do connect, the connection always has a complete media type. The purpose of the media type given by the filter graph manager is to limit the possible connection types.
During the negotiation process, the output pin proposes a media type by calling the input pin's IPin::ReceiveConnection method. The input pin can accept or reject the proposed type. This process repeats until either the input pin accepts a type, or the output pin runs out of types and the connection fails.
How an output pin selects media types to propose depends on the implementation. In the DirectShow base classes, the output pin calls IPin::EnumMediaTypes on the input pin. This method returns an enumerator that enumerates the input pin's preferred media types. Failing that, the output pin enumerates its own preferred types.
When two pins connect, they need a mechanism for exchanging media data. The mechanism is called the transport. In general, the DirectShow architecture is neutral about transports. Two filters can agree to connect using any transport that both support.
The most common transport is the local memory transport. With this transport, media data is held in main memory. An object called an allocator is responsible for allocating memory buffers. The allocator supports the IMemAllocator interface. (For more information, see Data Flow in the Filter Graph.) Input pins support local memory transport by exposing the IMemInputPin interface. The output pin queries for the interface during the connection process.
Both pins share the same allocator. When they connect, the pins negotiate which pin will supply the allocator, as follows:
Note that step 3 is the only required step in this process.
If a filter chooses an allocator from a downstream input pin, the filter must use the allocator only to deliver samples to that input pin. It must not use the allocator to deliver samples to other pins.
During a pin connection, a filter might need to disconnect and reconnect one of its other pins. For example:
To reconnect, the filter calls IFilterGraph::Reconnect or IFilterGraph2::ReconnectEx on the filter graph manager. The filter graph manager asynchronously disconnects and reconnects the pins. The ReconnectEx method is preferable, because it specifies a media type. Otherwise, the filter that initiates the reconnection must store the intended media type internally.
The filter must not attempt a reconnection unless the new connection is guaranteed to succeed. Otherwise, the pin will be left disconnected, causing graph errors. If the filter reconnects with a new media type, it must specify a media type known to be valid. If in doubt, call the IPin::QueryAccept method.
Also, the filter should request the reconnection from inside the IPin::Connect method, on the same thread. If the IPin::Connect method returns on one thread, while another thread makes the reconnection request, the filter graph manager might run the graph before it makes the reconnection, causing graph errors.