Поделиться через


Сравнение MFTs и динамических объектов интеллектуального анализа данных

Преобразования Media Foundation (MFTs) — это эволюция модели преобразования, впервые появилась с объектами мультимедиа DirectX (DMOS). В этом разделе приведены основные способы, в которых MFT отличаются от dmOS. Ознакомьтесь с этой статьей, если вы уже знакомы с интерфейсами DMO или хотите преобразовать существующий DMO в MFT.

В этом разделе содержатся следующие разделы:

Количество потоков

DMO имеет фиксированное количество потоков, а MFT может поддерживать динамическое число потоков. Клиент может добавлять входные потоки, а MFT может добавлять новые выходные потоки во время обработки. MFT не требуются для поддержки динамических потоков, однако. MFT может иметь фиксированное количество потоков, как DMO.

Следующие методы используются для поддержки динамических потоков на MFT:

Кроме того, метод IMFTransform::P rocessOutput определяет поведение для добавления или удаления выходных потоков.

Так как динамические объекты интеллектуального анализа данных имеют фиксированные потоки, потоки в DMO определяются с использованием значений индексов на основе нуля. С другой стороны, используйте идентификаторы потоков, которые не обязательно соответствуют значениям индекса. Это связано с тем, что количество потоков на MFT может измениться. Например, поток 0 может быть удален, оставляя поток 1 в качестве первого потока. Однако MFT с фиксированным числом потоков должно соблюдать то же соглашение, что и dmos, и использовать значения индексов для идентификаторов потоков.

Согласование формата

MFTs используют интерфейс IMFMediaType для описания типов мультимедиа. В противном случае согласование формата с MFTs работает с теми же основными принципами, что и с dmos. В следующей таблице перечислены методы согласования формата для dmos и соответствующие методы для MFT.

Метод DMO Метод MFT
IMediaObject::GetInputCurrentType МВФTransform::GetInputCurrentType
IMediaObject::GetInputMaxLatency IMFTransform::GetInputStreamInfo
IMediaObject::GetInputSizeInfo IMFTransform::GetInputStreamInfo
IMediaObject::GetInputType МВФTransform::GetInputAvailableType
IMediaObject::GetOutputCurrentType IMFTransform::GetOutputCurrentType
IMediaObject::GetOutputSizeInfo МВФTransform::GetOutputStreamInfo
IMediaObject::GetOutputType IMFTransform::GetOutputAvailableType

 

Течение

Как и для dmos, MFTs обрабатывают данные с помощью вызовов методов ProcessInput и ProcessOutput. Ниже приведены основные различия между процессами DMO и MFT при потоковой передаче данных.

Выделение ресурсов

MFTs не имеют методов IMediaObject::AllocateStreamingResources и IMediaObject::FreeStreamingResources, используемых с DMOS. Чтобы эффективно обрабатывать выделение и распределение ресурсов, MFT может реагировать на следующие сообщения в методе IMFTransform::P rocessMessage:

Кроме того, клиент может сигнализировать о запуске и завершении потока, вызвав ProcessMessage со следующими сообщениями:

Эти два сообщения не имеют точного эквивалента DMO.

Обработка данных

MFTs используют образцы мультимедиа для хранения входных и выходных данных. Примеры мультимедиа предоставляют интерфейс IMFSample и содержат следующие данные:

  • Метка времени и длительность.
  • Атрибуты, содержащие сведения о выборке. Список атрибутов см. в разделе примеры атрибутов.
  • Ноль или больше буферов мультимедиа. Каждый буфер мультимедиа предоставляет интерфейс IMFMediaBuffer.

Интерфейс IMFMediaBuffer аналогичен интерфейсу DMO IMediaBuffer. Чтобы получить доступ к базовому буферу памяти, вызовите IMFMediaBuffer::Lock. Этот метод примерно эквивалентен IMediaBuffer::GetBufferAndLength для DMOS.

Для несжатых видеоданных буфер мультимедиа также может поддерживать интерфейс МВФ2DBuffer. MFT, обрабатывающий несжатое видео (как входные или выходные данные), должен быть готов использовать интерфейс МВФ2DBuffer, если буфер предоставляет его. Дополнительные сведения см. в разделе Несжатые буферы видео.

Media Foundation предоставляет некоторые стандартные реализации МВФMediaBuffer, поэтому обычно не нужно писать собственную реализацию. Чтобы создать буфер DMO из буфера Media Foundation, вызовите MFCreateLegacyMediaBufferOnMFMediaBuffer.

Промывка

MFTs не имеют метода Flush. Чтобы очистить MFT, вызовите IMFTransform::P rocessMessage с сообщением MFT_MESSAGE_COMMAND_FLUSH.

Разрывы потока

MFTs не имеют метода отмены. Чтобы сигнализировать о прерывности в потоке, задайте атрибут MFSampleExtension_Discontinuity в входном примере.

Прочие различия

Ниже приведены некоторые дополнительные незначительные различия между MFTs и DMOS.

Флаги

В следующих таблицах перечислены различные флаги DMO и их эквиваленты MFT. Всякий раз, когда флаг DMO сопоставляется непосредственно с флагом MFT, оба флага имеют одинаковое числовое значение. Однако некоторые флаги DMO не имеют точных эквивалентов MFT, и наоборот.

Флаги ProcessInput

DmOs: перечисление _DMO_INPUT_DATA_BUFFER_FLAGS.

MFTs: нет эквивалентного перечисления.

Флаг DMO Флаг MFT
DMO_INPUT_DATA_BUFFERF_SYNCPOINT Нет эквивалентного флага. Вместо этого задайте для примера атрибут MFSampleExtension_CleanPoint.
DMO_INPUT_DATA_BUFFERF_TIME Нет эквивалентного флага. Вместо этого вызовите IMFSample::SetSampleTime в образце.
DMO_INPUT_DATA_BUFFERF_TIMELENGTH Нет эквивалентного флага. Вместо этого вызовите IMFSample::SetSampleDuration в примере.

 

Флаги ProcessOutput

DmOs: перечисление _DMO_PROCESS_OUTPUT_FLAGS.

MFTs: перечисление _MFT_PROCESS_OUTPUT_FLAGS.

Флаг DMO Флаг MFT
DMO_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER MFT_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER

 

DmOs: перечисление _DMO_OUTPUT_DATA_BUFFER_FLAGS.

MFTs: перечисление _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

DMOS: перечисление _DMO_INPUT_STATUS_FLAGS.

MFTs: перечисление _MFT_INPUT_STATUS_FLAGS.

Флаг DMO Флаг MFT
DMO_INPUT_STATUSF_ACCEPT_DATA MFT_INPUT_STATUS_ACCEPT_DATA

 

Флаги GetOutputStatus

DMOS: нет эквивалентного перечисления.

MFTs: перечисление _MFT_OUTPUT_STATUS_FLAGS.

Флаг DMO Флаг MFT
Нет эквивалентного флага. MFT_OUTPUT_STATUS_SAMPLE_READY

 

Флаги GetInputStreamInfo

DmOs: перечисление _DMO_INPUT_STREAM_INFO_FLAGS.

MFTs: перечисление _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

DmOs: перечисление _DMO_OUTPUT_STREAM_INFO_FLAGS.

MFTs: перечисление _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.

MFTs: перечисление _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 из методов МВФTransform. Коды ошибок 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. Таким образом, МВФTransform::P rocessInput становится МВФTransform::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.

преобразования Media Foundation