Аппаратные MFT
Примечание
Этот раздел относится к Windows 7 или более поздней версии.
В этом разделе описывается написание преобразования Media Foundation (MFT), которое выступает в качестве прокси-сервера для аппаратного кодировщика, декодера или цифрового обработчика сигналов (DSP).
Важно!
Если аппаратный кодек использует драйвер мультимедийного класса AVStream, ему не требуется настраиваемый MFT. Media Foundation предоставляет прокси-сервер AVStream для этой цели. Сведения в этом разделе применяются только в особом случае, когда аппаратный кодек не использует AVStream. Дополнительные сведения см. в разделе Поддержка аппаратного кодека в AVStream.
Этот раздел состоит из следующих подразделов.
- Введение
- Атрибуты MFT оборудования
- Последовательность подтверждения оборудования
- Обработка данных
- Сопряженный декодер/кодировщик
- Связанные темы
Введение
Любой аппаратный кодек, не основанный на AVStream, должен предоставлять собственный MFT для работы в качестве прокси-сервера для драйвера. Аппаратный кодек может включать несколько различных функциональных блоков:
- Кодировщик
- Декодер
- Масштабирование и преобразование формата кадров
Каждая из этих функций должна управляться отдельной функцией MFT. Аппаратный MFT никогда не должен выступать в качестве многоцелего «транскодера». Вместо этого поместите функции кодирования в кодировщик MFT, а декодирующие функции — в декодер MFT. Если оборудование предлагает масштабирование кадров и преобразование формата, поместите эти функции в отдельный видеопроцессор, зарегистрированный в категории MFT_CATEGORY_VIDEO_PROCESSOR . Если оборудование не поддерживает масштабирование кадров или преобразование формата, Media Foundation предоставляет программный видеопроцессор.
Аппаратные MFT имеют следующие общие требования:
- Аппаратные MFT должны использовать новую модель асинхронной обработки, как описано в разделе Асинхронные MFT.
- Аппаратные MFT должны поддерживать динамические изменения формата, как описано в разделе Динамические изменения формата.
Атрибуты MFT оборудования
Аппаратный MFT должен реализовывать следующие методы, связанные с атрибутами:
- IMFTransform::GetAttributes: возвращает хранилище атрибутов для глобальных атрибутов MFT.
- IMFTransform::GetInputStreamAttributes: возвращает хранилище атрибутов для входного потока.
- IMFTransform::GetOutputStreamAttributes: возвращает хранилище атрибутов для выходного потока.
При первом создании 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" использует системную память.
Чтобы установить аппаратное подключение, два аппаратных MFT должны использовать частный канал связи. Это соединение устанавливается во время согласования формата перед настройкой типов мультимедиа и перед первым вызовом ProcessInput. Процесс подключения выполняется следующим образом:
Загрузчик топологии проверяет наличие атрибута MFT_ENUM_HARDWARE_URL_Attribute в обоих MFT. Обратите внимание, что он не проверяет значение этого атрибута.
Если MFT_ENUM_HARDWARE_URL_Attribute присутствует в обоих MFT, загрузчик топологии выполняет следующие действия:
- Загрузчик топологии вызывает IMFTransform::GetOutputStreamAttributes на вышестоящий MFT (A). Этот метод возвращает указатель IMFAttributes . Пусть этот указатель будет обозначен pUpstream.
- Загрузчик топологии вызывает IMFTransform::GetInputStreamAttributes в подчиненном MFT (B). Этот вызов также возвращает указатель IMFAttributes . Пусть этот указатель будет обозначен как pDownstream.
- Загрузчик топологии задает атрибут MFT_CONNECTED_STREAM_ATTRIBUTE в pDownstream путем вызова IMFAttributes::SetUnknown. Значением атрибута является указатель PUpstream .
- Загрузчик топологии устанавливает для атрибута MFT_CONNECTED_TO_HW_STREAMзначение TRUE в pDownstream и pUpstream.
На этом этапе нижестоящий MFT имеет указатель на хранилище атрибутов MFT вышестоящий, как показано на следующей схеме.
Примечание
Для ясности на этой схеме показаны потоки и атрибуты, которые хранятся как отдельные объекты, но это не требуется для реализации.
Нижестоящий MFT использует указатель IMFAttributes для создания частного канала связи с вышестоящий MFT. Так как канал является частным, точный механизм определяется реализацией. Например, MFT может запрашивать частный COM-интерфейс.
На шаге 4 нижестоящий MFT должен проверить, используют ли два MFT одно и то же физическое устройство. Если нет, они должны вернуться к использованию системной памяти для передачи данных. Это позволяет MFT правильно работать с программными MFT и другими аппаратными устройствами.
Если подтверждение выполнено успешно и два MFT совместно используют частный канал данных, они не используют стандартную модель обработки данных (описанную в следующем разделе) в точке подключения. В частности, нижестоящий MFT не отправляет события METransformNeedInput ; Дополнительные сведения см. в следующем разделе этой статьи.
Обработка данных
Если аппаратный MFT использует системную память для передачи данных, процесс выполняется следующим образом:
- Чтобы запросить дополнительные входные данные, MFT отправляет событие METransformNeedInput .
- Событие METransformNeedInput приводит к тому, что конвейер вызывает IMFTransform::P rocessInput.
- Если MFT содержит выходные данные, MFT отправляет событие METransformHaveOutput .
- Событие METransformHaveOutput приводит к тому, что конвейер вызывает IMFTransform::P rocessOutput.
Дополнительные сведения см. в статье Асинхронные MFT.
Однако если MFT использует аппаратный канал, он не отправляет эти события в точку подключения оборудования, так как вся передача данных происходит внутри оборудования. Поэтому конвейер не вызывает ProcessInput или ProcessOutput в точке подключения.
Например, рассмотрим первую схему в этом разделе. При такой конфигурации обработка данных будет выполняться следующим образом:
- "A" отправляет METransformNeedInput для запроса данных.
- Конвейер вызывает ProcessInput для "A".
- "A" и "B" обрабатывают данные на оборудовании.
- После завершения обработки "B" отправляет событие METransformHaveOutput .
- Конвейер вызывает 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 должны возвращать только пользовательский формат, а не стандартные форматы.
Примечание
Если декодер не возвращает стандартные форматы, его нельзя использовать для воспроизведения с помощью расширенного отрисовщика видео. В этом случае он должен быть зарегистрирован как декодер только для перекода. См. раздел Декодеры только для перекода.
Связанные темы