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


Аппаратные MFT

Примечание

Этот раздел относится к Windows 7 или более поздней версии.

 

В этом разделе описывается написание преобразования Media Foundation (MFT), которое выступает в качестве прокси-сервера для аппаратного кодировщика, декодера или цифрового обработчика сигналов (DSP).

Важно!

Если аппаратный кодек использует драйвер мультимедийного класса AVStream, ему не требуется настраиваемый MFT. Media Foundation предоставляет прокси-сервер AVStream для этой цели. Сведения в этом разделе применяются только в особом случае, когда аппаратный кодек не использует AVStream. Дополнительные сведения см. в разделе Поддержка аппаратного кодека в AVStream.

 

Этот раздел состоит из следующих подразделов.

Введение

Любой аппаратный кодек, не основанный на AVStream, должен предоставлять собственный MFT для работы в качестве прокси-сервера для драйвера. Аппаратный кодек может включать несколько различных функциональных блоков:

  • Кодировщик
  • Декодер
  • Масштабирование и преобразование формата кадров

Каждая из этих функций должна управляться отдельной функцией MFT. Аппаратный MFT никогда не должен выступать в качестве многоцелего «транскодера». Вместо этого поместите функции кодирования в кодировщик MFT, а декодирующие функции — в декодер MFT. Если оборудование предлагает масштабирование кадров и преобразование формата, поместите эти функции в отдельный видеопроцессор, зарегистрированный в категории MFT_CATEGORY_VIDEO_PROCESSOR . Если оборудование не поддерживает масштабирование кадров или преобразование формата, Media Foundation предоставляет программный видеопроцессор.

Аппаратные MFT имеют следующие общие требования:

  • Аппаратные MFT должны использовать новую модель асинхронной обработки, как описано в разделе Асинхронные MFT.
  • Аппаратные MFT должны поддерживать динамические изменения формата, как описано в разделе Динамические изменения формата.

Атрибуты MFT оборудования

Аппаратный MFT должен реализовывать следующие методы, связанные с атрибутами:

При первом создании MFT он должен задать следующие атрибуты в собственном глобальном хранилище атрибутов (то есть хранилище атрибутов, возвращаемое GetAttributes):

attribute Описание
MF_TRANSFORM_ASYNC Должно быть задано значение TRUE. Указывает, что MFT выполняет асинхронную обработку.
MFT_ENUM_HARDWARE_URL_Attribute Содержит символьную ссылку для аппаратного устройства.
Загрузчик топологии использует наличие этого атрибута для проверки того, представляет ли MFT аппаратное устройство.
MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE Должно быть задано значение TRUE. Указывает, что MFT поддерживает динамические изменения формата.

 

Последовательность подтверждения оборудования

Если два MFT представляют одно и то же физическое устройство, они могут обмениваться данными внутри оборудования, например через аппаратную шину. Нет необходимости копировать данные в системную память, а затем обратно на устройство.

На следующей схеме MFT с метками "A" и "B" представляют функциональные блоки на одном оборудовании. Например, в сценарии перекодирования "A" может представлять аппаратный декодер, а "B" — аппаратный кодировщик. Поток данных между "A" и "B" происходит в пределах оборудования. MFT с меткой "C" является программным MFT. Поток данных из "B" в "C" использует системную память.

схема, показывающая поля с метками от a до c, а аппаратный кодек: указывает на b и кодек, кодек указывает на b, а b — на c

Чтобы установить аппаратное подключение, два аппаратных MFT должны использовать частный канал связи. Это соединение устанавливается во время согласования формата перед настройкой типов мультимедиа и перед первым вызовом ProcessInput. Процесс подключения выполняется следующим образом:

  1. Загрузчик топологии проверяет наличие атрибута MFT_ENUM_HARDWARE_URL_Attribute в обоих MFT. Обратите внимание, что он не проверяет значение этого атрибута.

  2. Если MFT_ENUM_HARDWARE_URL_Attribute присутствует в обоих MFT, загрузчик топологии выполняет следующие действия:

    1. Загрузчик топологии вызывает IMFTransform::GetOutputStreamAttributes на вышестоящий MFT (A). Этот метод возвращает указатель IMFAttributes . Пусть этот указатель будет обозначен pUpstream.
    2. Загрузчик топологии вызывает IMFTransform::GetInputStreamAttributes в подчиненном MFT (B). Этот вызов также возвращает указатель IMFAttributes . Пусть этот указатель будет обозначен как pDownstream.
    3. Загрузчик топологии задает атрибут MFT_CONNECTED_STREAM_ATTRIBUTE в pDownstream путем вызова IMFAttributes::SetUnknown. Значением атрибута является указатель PUpstream .
    4. Загрузчик топологии устанавливает для атрибута MFT_CONNECTED_TO_HW_STREAMзначение TRUE в pDownstream и pUpstream.
  3. На этом этапе нижестоящий MFT имеет указатель на хранилище атрибутов MFT вышестоящий, как показано на следующей схеме.

    схема с каждым mfts, указывающим на свой поток, каждый поток, указывающий на его хранилище, и хранилище входных данных с пунктирной линией к хранилищу выходных данных

    Примечание

    Для ясности на этой схеме показаны потоки и атрибуты, которые хранятся как отдельные объекты, но это не требуется для реализации.

     

  4. Нижестоящий MFT использует указатель IMFAttributes для создания частного канала связи с вышестоящий MFT. Так как канал является частным, точный механизм определяется реализацией. Например, MFT может запрашивать частный COM-интерфейс.

На шаге 4 нижестоящий MFT должен проверить, используют ли два MFT одно и то же физическое устройство. Если нет, они должны вернуться к использованию системной памяти для передачи данных. Это позволяет MFT правильно работать с программными MFT и другими аппаратными устройствами.

Если подтверждение выполнено успешно и два MFT совместно используют частный канал данных, они не используют стандартную модель обработки данных (описанную в следующем разделе) в точке подключения. В частности, нижестоящий MFT не отправляет события METransformNeedInput ; Дополнительные сведения см. в следующем разделе этой статьи.

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

Если аппаратный MFT использует системную память для передачи данных, процесс выполняется следующим образом:

  1. Чтобы запросить дополнительные входные данные, MFT отправляет событие METransformNeedInput .
  2. Событие METransformNeedInput приводит к тому, что конвейер вызывает IMFTransform::P rocessInput.
  3. Если MFT содержит выходные данные, MFT отправляет событие METransformHaveOutput .
  4. Событие METransformHaveOutput приводит к тому, что конвейер вызывает IMFTransform::P rocessOutput.

Дополнительные сведения см. в статье Асинхронные MFT.

Однако если MFT использует аппаратный канал, он не отправляет эти события в точку подключения оборудования, так как вся передача данных происходит внутри оборудования. Поэтому конвейер не вызывает ProcessInput или ProcessOutput в точке подключения.

Например, рассмотрим первую схему в этом разделе. При такой конфигурации обработка данных будет выполняться следующим образом:

  1. "A" отправляет METransformNeedInput для запроса данных.
  2. Конвейер вызывает ProcessInput для "A".
  3. "A" и "B" обрабатывают данные на оборудовании.
  4. После завершения обработки "B" отправляет событие METransformHaveOutput .
  5. Конвейер вызывает ProcessOutput для "B".

Сопряженный декодер/кодировщик

Если декодер и кодировщик расположены на одной аппаратной микросхеме, может быть предпочтительнее использовать их вместе при перекодировании. Это значит, что при выборе одного из них в конвейере перекодирования будет выбран другой. Чтобы обеспечить выбор соответствующих аппаратных кодеков, оба MFT кодека должны предлагать пользовательский тип мультимедиа. Чтобы создать пользовательский тип носителя, выполните приведенные далее действия.

  • Задайте для атрибута MF_MT_MAJOR_TYPEзначение MFMediaType_Audio или MFMediaType_Video соответствующим образом.
  • Задайте для атрибута MF_MT_SUBTYPE пользовательское значение GUID.

Другие атрибуты типа являются необязательными. Декодер возвращает пользовательский тип из своего imfTransform::GetOutputAvailableType, а кодировщик возвращает пользовательский тип из метода IMFTransform::GetInputAvailableType . В обоих случаях пользовательский тип должен быть первой записью в списке (dwTypeIndex = 0).

Для работы с программными кодеками кодек также должен возвращать по крайней мере один стандартный формат, например NV12 для видео. Стандартные форматы должны отображаться после пользовательского типа (dwTypeIndex> 0). Если два кодека всегда должны быть связаны и не могут взаимодействовать с программными кодеками, MFT должны возвращать только пользовательский формат, а не стандартные форматы.

Примечание

Если декодер не возвращает стандартные форматы, его нельзя использовать для воспроизведения с помощью расширенного отрисовщика видео. В этом случае он должен быть зарегистрирован как декодер только для перекода. См. раздел Декодеры только для перекода.

 

Написание пользовательского MFT

Реализация кодека MFT

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