Step 3. Support Media Type Negotiation

[The feature associated with this page, DirectShow, is a legacy feature. It has been superseded by MediaPlayer, IMFMediaEngine, and Audio/Video Capture in Media Foundation. Those features have been optimized for Windows 10 and Windows 11. Microsoft strongly recommends that new code use MediaPlayer, IMFMediaEngine and Audio/Video Capture in Media Foundation instead of DirectShow, when possible. Microsoft suggests that existing code that uses the legacy APIs be rewritten to use the new APIs if possible.]

This is step 3 of the tutorial Writing Transform Filters.

When two pins connect, they must agree on a media type for the connection. The media type describes the format of the data. Without the media type, a filter might deliver one kind of data, only to have another filter treat it as something else.

The basic mechanism for negotiating media types is the IPin::ReceiveConnection method. The output pin calls this method on the input pin with a proposed media type. The input pin accepts the connection or rejects it. If it rejects the connection, the output pin can try another media type. If no suitable types are found, the connection fails. Optionally, the input pin can advertise a list of types that it prefers, through the IPin::EnumMediaTypes method. The output pin can use this list when it proposes media types, although it does not have to.

The CTransformFilter class implements a general framework for this process, as follows:

  • The input pin has no preferred media types. It relies entirely on the upstream filter to propose the media type. For video data, this makes sense, because the media type includes the image size and the frame rate. Typically, that information must be supplied by an upstream source filter or parser filter. In the case of audio data, the set of possible formats is smaller, so it may be practical for the input pin to offer some preferred types. In that case, override CBasePin::GetMediaType on the input pin.
  • When the upstream filter proposes a media type, the input pin calls the CTransformFilter::CheckInputType method, which accepts or rejects the type.
  • The output pin will not connect unless the input pin is connected first. This behavior is typical for transform filters. In most cases, the filter must determine the input type before it can set the output type.
  • When the output pin does connect, it has a list of media types that it proposes to the downstream filter. It calls the CTransformFilter::GetMediaType method to generate this list. The output pin will also try any media types that the downstream filter proposes.
  • To check whether a particular output type is compatible with the input type, the output pin calls the CTransformFilter::CheckTransform method.

The three CTransformFilter methods listed previously are pure virtual methods, so your derived class must implement them. None of these methods belongs to a COM interface; they are simply part of the implementation provided by the base classes.

The following sections describe each method in more detail:

How Filters Connect

Writing DirectShow Filters