Сравнение преобразований MFT и объектов DMO
Преобразования Media Foundation (MFT) — это эволюция модели преобразования, впервые появилась с объектами мультимедиа (DMOS) DirectX. В этом разделе перечислены main отличия MFT от МДО. Прочтите этот раздел, если вы уже знакомы с интерфейсами DMO или хотите преобразовать существующий объект DMO в MFT.
Этот раздел состоит из следующих подразделов.
- Число потоков
- Согласование формата
- Потоковая передача
- Прочие различия
- Flags
- Код ошибки
- Создание гибридных объектов DMO/MFT
- Связанные темы
Число потоков
DMO имеет фиксированное число потоков, а MFT может поддерживать динамическое число потоков. Клиент может добавлять входные потоки, а MFT — новые потоки вывода во время обработки. Однако MFT не требуются для поддержки динамических потоков. MFT может иметь фиксированное количество потоков, как и DMO.
Для поддержки динамических потоков на MFT используются следующие методы:
- IMFTransform::AddInputStreams
- IMFTransform::D eleteInputStream
- IMFTransform::GetStreamIDs
- IMFTransform::GetStreamLimits
Кроме того, метод IMFTransform::P rocessOutput определяет поведение при добавлении или удалении потоков вывода.
Так как У МДО имеются фиксированные потоки, потоки в DMO определяются с помощью значений индекса, отсчитываемых от нуля. С другой стороны, MFT используют идентификаторы потоков, которые не обязательно соответствуют значениям индекса. Это связано с тем, что количество потоков на MFT может измениться. Например, поток 0 можно удалить, оставив поток 1 в качестве первого потока. Однако MFT с фиксированным числом потоков должен соблюдать то же соглашение, что и МД, и использовать значения индекса для идентификаторов потоков.
Согласование формата
MFT используют интерфейс IMFMediaType для описания типов мультимедиа. В противном случае согласование формата с помощью MFT работает на те же основные принципы, что и в случае с МДО. В следующей таблице перечислены методы согласования формата для dmos и соответствующие методы для MFT.
Потоковые операторы
Как и объекты управления административными данными, MFT обрабатывают данные с помощью вызовов методов ProcessInput и ProcessOutput . Ниже приведены основные различия между процессами DMO и MFT при потоковой передаче данных.
Выделение ресурсов
В MFT нет методов IMediaObject::AllocateStreamingResources и IMediaObject::FreeStreamingResources, используемых с объектами административного управления. Для эффективной обработки распределения и освобождения ресурсов MFT может реагировать на следующие сообщения в методе IMFTransform::P rocessMessage :
Кроме того, клиент может сообщить о начале и конце потока, вызвав ProcessMessage со следующими сообщениями:
Эти два сообщения не имеют точного эквивалента DMO.
Обработка данных
MFT используют примеры мультимедиа для хранения входных и выходных данных. Примеры мультимедиа предоставляют интерфейс IMFSample и содержат следующие данные:
- Метка времени и длительность.
- Атрибуты, содержащие сведения для каждого примера. Список атрибутов см. в разделе Пример атрибутов.
- Ноль или более буферов мультимедиа. Каждый буфер мультимедиа предоставляет интерфейс IMFMediaBuffer .
Интерфейс IMFMediaBuffer аналогичен интерфейсу IMediaBuffer DMO. Чтобы получить доступ к базовому буферу памяти, вызовите IMFMediaBuffer::Lock. Этот метод примерно эквивалентен IMediaBuffer::GetBufferAndLength для объектов dmos.
Для несжатых видеоданных буфер мультимедиа также может поддерживать интерфейс IMF2DBuffer . MFT, обрабатывающий несжатое видео (в качестве входных или выходных данных), должен быть подготовлен к использованию интерфейса IMF2DBuffer , если буфер предоставляет его. Дополнительные сведения см. в разделе Несжатые буферы видео.
Media Foundation предоставляет некоторые стандартные реализации IMFMediaBuffer, поэтому обычно не требуется писать собственную реализацию. Чтобы создать буфер DMO из буфера Media Foundation, вызовите MFCreateLegacyMediaBufferOnMFMediaBuffer.
Промывки
В MFT нет метода Flush . Чтобы очистить MFT, вызовите IMFTransform::P rocessMessage с сообщением MFT_MESSAGE_COMMAND_FLUSH .
Прерывания потоков
MFT не имеют метода Прерывания . Чтобы сообщить о разрыве потока, задайте атрибут MFSampleExtension_Discontinuity для входной выборки.
Прочие различия
Ниже приведены некоторые дополнительные незначительные различия между MFT и dmos.
Для следующих методов DMO не существует эквивалентов MFT:
MFT не требуются для поддержки агрегирования.
MFT поддерживают операцию, называемую очисткой. Целью очистки является обработка всех данных, которые остаются в MF, без предоставления дополнительных входных данных в MFT (например, в конце потока). Чтобы истощить MFT, позвоните по телефону IMFTransform::P rocessMessage с MFT_MESSAGE_COMMAND_DRAIN сообщением. Дополнительные сведения см. в разделе Базовая модель обработки MFT.
MFT могут иметь атрибуты, в том числе атрибуты для каждого потока. Используйте следующие методы, чтобы получить атрибуты из MFT:
MFT могут обрабатывать события. Чтобы отправить событие в MFT, позвоните по телефону IMFTransform::P rocessEvent. MFT может отправить событие клиенту с помощью метода ProcessOutput . Дополнительные сведения см. в разделе Базовая модель обработки MFT.
Флаги
В следующих таблицах перечислены различные флаги DMO и их эквиваленты MFT. Всякий раз, когда флаг DMO сопоставляется непосредственно с флагом MFT, оба флага имеют одинаковое числовое значение. Однако некоторые флаги DMO не имеют точных эквивалентов MFT и наоборот.
Флаги ProcessInput
МДО: перечисление _DMO_INPUT_DATA_BUFFER_FLAGS .
MFT: нет эквивалентного перечисления.
Флаг DMO | Флаг MFT |
---|---|
DMO_INPUT_DATA_BUFFERF_SYNCPOINT | Нет эквивалентного флага. Вместо этого задайте атрибут MFSampleExtension_CleanPoint в примере. |
DMO_INPUT_DATA_BUFFERF_TIME | Нет эквивалентного флага. Вместо этого вызовите IMFSample::SetSampleTime в образце. |
DMO_INPUT_DATA_BUFFERF_TIMELENGTH | Нет эквивалентного флага. Вместо этого вызовите IMFSample::SetSampleDuration в образце. |
Флаги ProcessOutput
МДО: перечисление _DMO_PROCESS_OUTPUT_FLAGS .
MFT: перечисление _MFT_PROCESS_OUTPUT_FLAGS .
Флаг DMO | Флаг MFT |
---|---|
DMO_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER | MFT_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER |
МДО: перечисление _DMO_OUTPUT_DATA_BUFFER_FLAGS .
MFT: перечисление _MFT_OUTPUT_DATA_BUFFER_FLAGS .
Флаг DMO | Флаг MFT |
---|---|
DMO_OUTPUT_DATA_BUFFERF_SYNCPOINT | Нет эквивалентного флага. Вместо этого проверка для атрибута MFSampleExtension_CleanPoint в примере. |
DMO_OUTPUT_DATA_BUFFERF_TIME | Нет эквивалентного флага. Вместо этого вызовите imfSample::GetSampleTime в образце. |
DMO_OUTPUT_DATA_BUFFERF_TIMELENGTH | Нет эквивалентного флага. Вместо этого вызовите IMFSample::GetSampleDuration в образце. |
DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE | MFT_OUTPUT_DATA_BUFFER_INCOMPLETE |
Нет эквивалентного флага. | MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE |
Нет эквивалентного флага. | MFT_OUTPUT_DATA_BUFFER_STREAM_END |
Нет эквивалентного флага. | MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE |
Флаги GetInputStatus
МДО: перечисление _DMO_INPUT_STATUS_FLAGS .
MFT: перечисление _MFT_INPUT_STATUS_FLAGS .
Флаг DMO | Флаг MFT |
---|---|
DMO_INPUT_STATUSF_ACCEPT_DATA | MFT_INPUT_STATUS_ACCEPT_DATA |
Флаги GetOutputStatus
МДО: нет эквивалентного перечисления.
MFT: перечисление _MFT_OUTPUT_STATUS_FLAGS .
Флаг DMO | Флаг MFT |
---|---|
Нет эквивалентного флага. | MFT_OUTPUT_STATUS_SAMPLE_READY |
Флаги GetInputStreamInfo
МДО: перечисление _DMO_INPUT_STREAM_INFO_FLAGS .
MFT: перечисление _MFT_INPUT_STREAM_INFO_FLAGS .
Флаг DMO | Флаг MFT |
---|---|
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 |
Нет эквивалентного флага. | MFT_INPUT_STREAM_DOES_NOT_ADDREF |
Нет эквивалентного флага. | MFT_INPUT_STREAM_REMOVABLE |
Нет эквивалентного флага. | MFT_INPUT_STREAM_OPTIONAL |
Флаги GetOutputStreamInfo
МДО: перечисление _DMO_OUTPUT_STREAM_INFO_FLAGS .
MFT: перечисление _MFT_OUTPUT_STREAM_INFO_FLAGS .
Флаг DMO | Флаг MFT |
---|---|
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 |
Нет эквивалентного флага. | MFT_OUTPUT_STREAM_PROVIDES_SAMPLES |
Нет эквивалентного флага. | MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES |
Нет эквивалентного флага. | MFT_OUTPUT_STREAM_LAZY_READ |
Нет эквивалентного флага. | MFT_OUTPUT_STREAM_REMOVABLE |
Флаги SetInputType/SetOutputType
DmOs: перечисление _DMO_SET_TYPE_FLAGS .
MFT: перечисление _MFT_SET_TYPE_FLAGS .
Флаг DMO | Флаг MFT |
---|---|
DMO_SET_TYPEF_TEST_ONLY | MFT_SET_TYPE_TEST_ONLY |
DMO_SET_TYPEF_CLEAR | Нет эквивалентного флага. Вместо этого присвойте типу носителя значение NULL , чтобы очистить тип мультимедиа. |
Коды ошибок
В следующей таблице показано, как сопоставить коды ошибок DMO с кодами ошибок MFT. Гибридный объект MFT/DMO должен возвращать коды ошибок DMO из методов IMediaObject и коды ошибок MFT из методов IMFTransform . Коды ошибок DMO определяются в файле заголовка MediaErr.h. Коды ошибок MFT определяются в файле заголовка mferror.h.
Код ошибки DMO | Код ошибки MFT |
---|---|
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 |
Создание гибридных объектов DMO/MFT
Интерфейс IMFTransform слабо основан на IMediaObject, который является основным интерфейсом для объектов мультимедиа DirectX (DMOS). Можно создать объекты, которые предоставляют оба интерфейса. Однако это может привести к конфликтам имен, так как интерфейсы имеют некоторые методы с одинаковыми именами. Эту проблему можно решить одним из двух способов:
Решение 1. Добавьте следующую строку в начало любого CPP-файла, содержащего функции MFT:
#define MFT_UNIQUE_METHOD_NAMES
При этом объявление интерфейса IMFTransform изменяется таким образом, что большинство имен методов имеют префикс "MFT". Таким образом, IMFTransform::P rocessInput становится IMFTransform::MFTProcessInput, а IMediaObject::P rocessInput сохраняет свое первоначальное имя. Этот метод наиболее полезен при преобразовании существующего объекта DMO в гибридное DMO/MFT. Вы можете добавить новые методы MFT, не изменяя методы DMO.
Решение 2. Используйте синтаксис C++ для устранения неоднозначности имен, унаследованных от нескольких интерфейсов. Например, объявите MFT-версию ProcessInput следующим образом:
CMyHybridObject::IMFTransform::ProcessInput(...)
Объявите версию DMO ProcessInput следующим образом:
CMyHybridObject::IMediaObject::ProcessInput(...)
При внутреннем вызове метода в объекте можно использовать этот синтаксис, но это переопределит виртуальное состояние метода. Лучший способ выполнения вызовов из объекта :
hr = ((IMediaObject*)this)->ProcessInput(...)
Таким образом, если вы наследуете другой класс от CMyHybridObject и переопределите метод CMyHybridObject::IMediaObject::P rocessInput, вызывается правильный виртуальный метод. Интерфейсы DMO описаны в документации по пакету SDK DirectShow.
Связанные темы