Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Преобразования Media Foundation (MFTs) — это эволюция модели преобразования, впервые появилась с объектами мультимедиа DirectX (DMOS). В этом разделе приведены основные способы, в которых MFT отличаются от dmOS. Ознакомьтесь с этой статьей, если вы уже знакомы с интерфейсами DMO или хотите преобразовать существующий DMO в MFT.
В этом разделе содержатся следующие разделы:
- число потоков
- форматирование
- потоковой передачи
- прочие различия
- флаги
- Флаги ProcessInput
- флаги processOutput
- Флаги GetInputStatus
- флаги GetOutputStatus
- флаги GetInputStreamInfo
- флаги GetOutputStreamInfo
- Флаги SetInputType/SetOutputType
- коды ошибок
- создание гибридных объектов DMO/MFT
- связанные разделы
Количество потоков
DMO имеет фиксированное количество потоков, а MFT может поддерживать динамическое число потоков. Клиент может добавлять входные потоки, а MFT может добавлять новые выходные потоки во время обработки. MFT не требуются для поддержки динамических потоков, однако. MFT может иметь фиксированное количество потоков, как DMO.
Следующие методы используются для поддержки динамических потоков на MFT:
- МВФTransform::AddInputStreams
- IMFTransform::D eleteInputStream
- МВФTransform::GetStreamIDs
- МВФTransform::GetStreamLimits
Кроме того, метод IMFTransform::P rocessOutput определяет поведение для добавления или удаления выходных потоков.
Так как динамические объекты интеллектуального анализа данных имеют фиксированные потоки, потоки в DMO определяются с использованием значений индексов на основе нуля. С другой стороны, используйте идентификаторы потоков, которые не обязательно соответствуют значениям индекса. Это связано с тем, что количество потоков на MFT может измениться. Например, поток 0 может быть удален, оставляя поток 1 в качестве первого потока. Однако MFT с фиксированным числом потоков должно соблюдать то же соглашение, что и dmos, и использовать значения индексов для идентификаторов потоков.
Согласование формата
MFTs используют интерфейс IMFMediaType для описания типов мультимедиа. В противном случае согласование формата с MFTs работает с теми же основными принципами, что и с dmos. В следующей таблице перечислены методы согласования формата для dmos и соответствующие методы для MFT.
Течение
Как и для 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:
Для поддержки агрегирования не требуются MFT.
MFTs поддерживает операцию, называемую очистки. Целью очистки является обработка любых данных, которые остаются в MF, без предоставления дополнительных входных данных MFT (например, в конце потока). Чтобы слить MFT, вызовите МВФTransform::P rocessMessage с сообщением MFT_MESSAGE_COMMAND_DRAIN. Дополнительные сведения см. в разделе Базовая модель обработки MFT.
MFTs могут иметь атрибуты, включая атрибуты для каждого потока. Используйте следующие методы, чтобы получить атрибуты из MFT:
MFT может обрабатывать события. Чтобы отправить событие на MFT, вызовите МВФTransform::P rocessEvent. MFT может отправлять событие клиенту через метод ProcessOutput. Дополнительные сведения см. в разделе Базовая модель обработки MFT.
Флаги
В следующих таблицах перечислены различные флаги 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.
Связанные разделы