Redigera

Dela via


Comparison of MFTs and DMOs

Media Foundation transforms (MFTs) are an evolution of the transform model first introduced with DirectX Media Objects (DMOs). This topic summarizes the main ways in which MFTs differ from DMOs. Read this topic if you are already familiar with the DMO interfaces, or if you want to convert an existing DMO into an MFT.

This topic contains the following sections:

Number of Streams

A DMO has a fixed number of streams, while an MFT can support a dynamic number of streams. The client can add input streams, and the MFT can add new output streams during processing. MFTs are not required to support dynamic streams, however. An MFT can have a fixed number of streams, just like a DMO.

The following methods are used to support dynamic streams on an MFT:

In addition, the IMFTransform::ProcessOutput method defines the behavior for adding or removing output streams.

Because DMOs have fixed streams, the streams on a DMO are identified using zero-based index values. MFTs, on the other hand, use stream identifiers that do not necessarily correspond to index values. This is because the number of streams on an MFT might change. For example, stream 0 might be removed, leaving stream 1 as the first stream. However, an MFT with a fixed number of streams should observe the same convention as DMOs and use index values for stream identifiers.

Format Negotiation

MFTs use the IMFMediaType interface to describe media types. Otherwise, format negotiation with MFTs works on the same basic principles as with DMOs. The following table lists the format negotiation methods for DMOs and the corresponding methods for MFTs.

DMO method MFT method
IMediaObject::GetInputCurrentType IMFTransform::GetInputCurrentType
IMediaObject::GetInputMaxLatency IMFTransform::GetInputStreamInfo
IMediaObject::GetInputSizeInfo IMFTransform::GetInputStreamInfo
IMediaObject::GetInputType IMFTransform::GetInputAvailableType
IMediaObject::GetOutputCurrentType IMFTransform::GetOutputCurrentType
IMediaObject::GetOutputSizeInfo IMFTransform::GetOutputStreamInfo
IMediaObject::GetOutputType IMFTransform::GetOutputAvailableType

 

Streaming

Like DMOs, MFTs process data through calls to ProcessInput and ProcessOutput methods. Here are the major differences between DMO and MFT processes when streaming data.

Allocating Resources

MFTs do not have the IMediaObject::AllocateStreamingResources and IMediaObject::FreeStreamingResources methods used with DMOs. To handle allocation and deallocation of resources efficiently, an MFT can respond to the following messages in the IMFTransform::ProcessMessage method:

In addition, the client can signal the start and end of a stream by calling ProcessMessage with the following messages:

These two messages have no exact DMO equivalent.

Processing Data

MFTs use media samples to hold input and output data. Media samples expose the IMFSample interface, and contain the following data:

  • Time stamp and duration.
  • Attributes that contain per-sample information. For a list of attributes, see Sample Attributes.
  • Zero or more media buffers. Each media buffer exposes the IMFMediaBuffer interface.

The IMFMediaBuffer interface is similar to the DMO IMediaBuffer interface. To access the underlying memory buffer, call IMFMediaBuffer::Lock. This method is roughly equivalent to IMediaBuffer::GetBufferAndLength for DMOs.

For uncompressed video data, a media buffer might also support the IMF2DBuffer interface. An MFT that processes uncompressed video (either as input or output) should be prepared to use the IMF2DBuffer interface if the buffer exposes it. For more information, see Uncompressed Video Buffers.

Media Foundation provides some standard implementations of IMFMediaBuffer, so it is generally not necessary to write your own implementation. To create a DMO buffer from a Media Foundation buffer, call MFCreateLegacyMediaBufferOnMFMediaBuffer.

Flushing

MFTs do not have a Flush method. To flush an MFT, call IMFTransform::ProcessMessage with the MFT_MESSAGE_COMMAND_FLUSH message.

Stream Discontinuities

MFTs do not have a Discontinuity method. To signal a discontinuity in a stream, set the MFSampleExtension_Discontinuity attribute on the input sample.

Miscellaneous Differences

Here are some additional minor differences between MFTs and DMOs.

Flags

The following tables list the various DMO flags and their MFT equivalents. Whenever a DMO flag maps directly to an MFT flag, both flags have the same numeric value. However, some DMO flags do not have exact MFT equivalents, and vice versa.

ProcessInput Flags

DMOs: _DMO_INPUT_DATA_BUFFER_FLAGS enumeration.

MFTs: No equivalent enumeration.

DMO flag MFT flag
DMO_INPUT_DATA_BUFFERF_SYNCPOINT No equivalent flag. Instead, set the MFSampleExtension_CleanPoint attribute on the sample.
DMO_INPUT_DATA_BUFFERF_TIME No equivalent flag. Instead, call IMFSample::SetSampleTime on the sample.
DMO_INPUT_DATA_BUFFERF_TIMELENGTH No equivalent flag. Instead, call IMFSample::SetSampleDuration on the sample.

 

ProcessOutput Flags

DMOs: _DMO_PROCESS_OUTPUT_FLAGS enumeration.

MFTs: _MFT_PROCESS_OUTPUT_FLAGS enumeration.

DMO flag MFT flag
DMO_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER MFT_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER

 

DMOs: _DMO_OUTPUT_DATA_BUFFER_FLAGS enumeration.

MFTs: _MFT_OUTPUT_DATA_BUFFER_FLAGS enumeration.

DMO flag MFT flag
DMO_OUTPUT_DATA_BUFFERF_SYNCPOINT No equivalent flag. Instead, check for the MFSampleExtension_CleanPoint attribute on the sample.
DMO_OUTPUT_DATA_BUFFERF_TIME No equivalent flag. Instead, call IMFSample::GetSampleTime on the sample.
DMO_OUTPUT_DATA_BUFFERF_TIMELENGTH No equivalent flag. Instead, call IMFSample::GetSampleDuration on the sample.
DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
No equivalent flag. MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE
No equivalent flag. MFT_OUTPUT_DATA_BUFFER_STREAM_END
No equivalent flag. MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE

 

GetInputStatus Flags

DMOs: _DMO_INPUT_STATUS_FLAGS enumeration.

MFTs: _MFT_INPUT_STATUS_FLAGS enumeration.

DMO flag MFT flag
DMO_INPUT_STATUSF_ACCEPT_DATA MFT_INPUT_STATUS_ACCEPT_DATA

 

GetOutputStatus Flags

DMOs: No equivalent enumeration.

MFTs: _MFT_OUTPUT_STATUS_FLAGS enumeration.

DMO flag MFT flag
No equivalent flag. MFT_OUTPUT_STATUS_SAMPLE_READY

 

GetInputStreamInfo Flags

DMOs: _DMO_INPUT_STREAM_INFO_FLAGS enumeration.

MFTs: _MFT_INPUT_STREAM_INFO_FLAGS enumeration.

DMO flag MFT flag
DMO_INPUT_STREAMF_WHOLE_SAMPLES MFT_INPUT_STREAM_WHOLE_SAMPLES
DMO_INPUT_STREAMF_SINGLE_SAMPLE_PER_BUFFER MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
DMO_INPUT_STREAMF_FIXED_SAMPLE_SIZE MFT_INPUT_STREAM_FIXED_SAMPLE_SIZE
DMO_INPUT_STREAMF_HOLDS_BUFFERS MFT_INPUT_STREAM_HOLDS_BUFFERS
No equivalent flag. MFT_INPUT_STREAM_DOES_NOT_ADDREF
No equivalent flag. MFT_INPUT_STREAM_REMOVABLE
No equivalent flag. MFT_INPUT_STREAM_OPTIONAL

 

GetOutputStreamInfo Flags

DMOs: _DMO_OUTPUT_STREAM_INFO_FLAGS enumeration.

MFTs: _MFT_OUTPUT_STREAM_INFO_FLAGS enumeration.

DMO flag MFT flag
DMO_OUTPUT_STREAMF_WHOLE_SAMPLES MFT_OUTPUT_STREAM_WHOLE_SAMPLES
DMO_OUTPUT_STREAMF_SINGLE_SAMPLE_PER_BUFFER MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
DMO_OUTPUT_STREAMF_FIXED_SAMPLE_SIZE MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE
DMO_OUTPUT_STREAMF_DISCARDABLE MFT_OUTPUT_STREAM_DISCARDABLE
DMO_OUTPUT_STREAMF_OPTIONAL MFT_OUTPUT_STREAM_OPTIONAL
No equivalent flag. MFT_OUTPUT_STREAM_PROVIDES_SAMPLES
No equivalent flag. MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES
No equivalent flag. MFT_OUTPUT_STREAM_LAZY_READ
No equivalent flag. MFT_OUTPUT_STREAM_REMOVABLE

 

SetInputType/SetOutputType Flags

DMOs: _DMO_SET_TYPE_FLAGS enumeration.

MFTs: _MFT_SET_TYPE_FLAGS enumeration.

DMO flag MFT flag
DMO_SET_TYPEF_TEST_ONLY MFT_SET_TYPE_TEST_ONLY
DMO_SET_TYPEF_CLEAR No equivalent flag. Instead, set the media type to NULL to clear the media type.

 

Error Codes

The following table shows how to map DMO error codes to MFT error codes. A hybrid MFT/DMO object should return the DMO error codes from IMediaObject methods and the MFT error codes from IMFTransform methods. The DMO error codes are defined in the header file MediaErr.h. The MFT error codes are defined in the header file mferror.h.

DMO error code MFT error code
DMO_E_INVALIDTYPE MF_E_INVALIDTYPE
DMO_E_INVALIDSTREAMINDEX MF_E_INVALIDSTREAMNUMBER
DMO_E_NOTACCEPTING MF_E_NOTACCEPTING
DMO_E_NO_MORE_ITEMS MF_E_NO_MORE_TYPES
DMO_E_TYPE_NOT_ACCEPTED MF_E_INVALIDMEDIATYPE
DMO_E_TYPE_NOT_SET MF_E_TRANSFORM_TYPE_NOT_SET

 

Creating Hybrid DMO/MFT Objects

The IMFTransform interface is loosely based on IMediaObject, which is the primary interface for DirectX Media Objects (DMOs). It is possible to create objects that expose both interfaces. However, this can lead to naming collisions, because the interfaces have some methods that share the same name. You can solve this problem in one of two ways:

Solution 1: Include the following line at the top of any .cpp file that contains MFT functions:

#define MFT_UNIQUE_METHOD_NAMES

This changes the declaration of the IMFTransform interface so that most of the method names are prefixed with "MFT". Thus, IMFTransform::ProcessInput becomes IMFTransform::MFTProcessInput, while IMediaObject::ProcessInput keeps its original name. This technique is most useful if you are converting an existing DMO to a hybrid DMO/MFT. You can add the new MFT methods without changing the DMO methods.

Solution 2: Use C++ syntax to disambiguate names that are inherited from more than one interface. For example, declare the MFT version of ProcessInput as follows:

CMyHybridObject::IMFTransform::ProcessInput(...)

Declare the DMO version of ProcessInput like this:

CMyHybridObject::IMediaObject::ProcessInput(...)

If you make an internal call to a method within the object, you can use this syntax, but doing so will override the virtual status of the method. A better way to make calls from inside the object is the following:

hr = ((IMediaObject*)this)->ProcessInput(...)

That way, if you derive another class from CMyHybridObject and override the CMyHybridObject::IMediaObject::ProcessInput method, the correct virtual method is called. The DMO interfaces are documented in the DirectShow SDK documentation.

Media Foundation Transforms