Microsoft DirectX 8.1 (C++) |
When pins from different filters are connected, they must both agree on a common media type for the samples they will exchange. A quick review of the connection mechanism might help highlight how transform filters handle media type negotiations.
This section contains the following topics:
When one filter's output pin is called by the Filter Graph Manager to connect to an input pin of a second filter, the IPin::Connect method is called. This, in turn, calls CBaseOutputPin::CheckConnect to obtain interfaces from the connected pin and CBasePin::AgreeMediaType to find a common media type.
AgreeMediaType calls CBasePin::TryMediaTypes, which uses media type enumerators to query the pins for preferred media types. IEnumMediaTypes is an interface on the connected input pin that TryMediaTypes uses first. The base classes use IEnumMediaTypes to repeatedly call a CBasePin member function called GetMediaType for each media type in the list. You use this member function in your input and output pin classes to return the media types that your pin prefers.
TryMediaTypes calls the output pin's CheckMediaType member function with each input type returned. You must use CheckMediaType to verify whether this type is acceptable. If no media types are found (for example GetMediaType might not even be used on the connected input pin, or might return an unacceptable media type), then AgreeMediaType obtains a media type enumerator for the output pin and tries each of these in turn. Again, the GetMediaType member function of the derived output pin is called for each type. In this case, it can determine media types by inquiring about any existing connection established by the filter's input pin.
For transform filters that do not modify the media type from input pin to output pin (such as most in-place transforms and many copy transforms), a reconnection scheme must be in place for offering the downstream filter's media type to the upstream filter. To understand this, consider the media type negotiation of the transform-in-place Filter B in the following illustration.
The input pin of Filter B is connected first and establishes a media type with the upstream output pin (AOutPin). When the output pin of Filter B is connected next, it must use the enumerator from the output pin of the connected upstream filter (AOutPin), because it does not have one of its own.
If the pin of the downstream filter, CInPin, can accept this, then the connection is complete. However, assume that Filter C does not agree to this media type but proposes a media type that Filter B can handle.
Before deciding that it can handle the media type, Filter B calls the IPin::QueryAccept method on AOutPin to ensure that it is acceptable. If no media type can be found that is acceptable for all the filters, then the BOutPin to CInPin connection will fail. (It is possible to find that a transform-in-place filter will connect to either its upstream or its downstream neighbors, but not both simultaneously.)
If a suitable type is found, BOutPin must force a reconnection on the entire filter, and pass the established media type (the media type of CInPin) to AOutPin, when AOutPin and BInPin are connected again.