Реализация Media Foundation Transform (MFT) с DirectX Video Acceleration (DXVA)

Целью является реализация пользовательского MFT для обработки видео и синхронизации с внешним приложением. Подробности не важны.
В качестве первого шага я бы хотел получить и запустить MFT с использованием обработки видео DXVA или DXVA-HD. Я не смог этого сделать.

Вот что я сделал:
Я начал строить топологию с исходного узла ввода (моя веб-камера), MFT (пример MFT_Grayscale) и EVR.
Я включил это в небольшое приложение. Топология работала, и я мог видеть монохромный поток с камеры.
Теперь я хочу изменить код примера MF_Grayscale таким образом, чтобы он поддерживал обработку видео DXVA и мог использовать аппаратное ускорение, предоставляемое методом VideoProcessBlt.
Документация Microsoft дает кусочки информации, но я не смог добиться работающего MFT.

Что я сделал до сих пор:

  • В методе GetAttributes Я указываю, что это MFT MF_SA_D3D_AWARE,
  • В методе ProcessMessage Я обрабатываю сообщение MFT_MESSAGE_SET_D3D_MANAGER чтобы получить дескриптор устройства, IDirect3DDeviceManager9 и IDirectXVideoProcessorService,
  • в SetInputType метод я использую методы, описанные здесь
    https://msdn.microsoft.com/en-us/library/windows/desktop/ms694235(v=vs.85).aspx
    получить структуру DXVA2_VideoDesc
    и следуйте этому коду
    https://msdn.microsoft.com/en-us/library/windows/desktop/cc307964(v=vs.85).aspx
    создать устройство обработки видео. Дополнительно я создаю поверхности, используя
    IDirectXVideoProcessorService->CreateSurface
  • В методе GetOutputStreamInfo dwFlags переменная выглядит так:

pStreamInfo->dwFlags =
MFT_OUTPUT_STREAM_PROVIDES_SAMPLES |
MFT_OUTPUT_STREAM_WHOLE_SAMPLES |
MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER |
MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE;

Кажется, пока все в порядке. Теперь мои вопросы (извините, что не могу быть более конкретным):

  • Должен ли я адаптировать GetOutputAvailableType/SetOutputType методы?

  • в ProcessInput метод я получаю IMFSample и извлечь IMFMediaBuffer, Буфер не управляет IDirect3DSurface9 согласно моим вызовам функций.
    Нужно ли мне записывать данные из буфера на поверхность Direct3D?

  • в ProcessOutput способ сделать отправную точку, я хочу, чтобы переслать входящий кадр на выход. VideoProcessBlt должен сделать 1: 1 блиц от входа до выхода.
    В документации сказано:

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

Как я могу определить, используется ли поверхность?

  • Как я должен вывести поверхность? Должен ли я использовать MFCreateVideoSampleFromSurface или же MFCreateDXSurfaceBuffer?

  • К сожалению, я действительно потерян и не могу добиться прогресса, используя документацию.

Ситуация сейчас такова, что я не вижу никакого видеовыхода (у окна есть цвет фона по умолчанию для окон), и веб-камера перестает захватывать кадры после первого кадра (светодиод выключается). Кроме того, ничего не происходит — приложение просто продолжает работать, ничего не показывая).

Я надеюсь, что кто-нибудь может мне помочь. Я также был бы признателен, если бы кто-то мог направить меня к образцу кода для MFT с использованием обработки видео DXVA или DXVA-HD. Я не смог ничего найти …

Спасибо

5

Решение

Нужно ли адаптировать методы GetOutputAvailableType / SetOutputType?

Да. Вы должны предоставить атрибуты как обычно, без особых требований.

Нужно ли мне записывать данные из буфера на поверхность Direct3D?

Да. При этом вам нужно заботиться о IDirect3DDeviceManager9 и LockDevice, поскольку EVR может одновременно использовать поверхность.

Как я могу определить, используется ли поверхность?

Вы должны заботиться особенно, когда поверхность свободна для использования. В вашем MFT должен быть реализован интерфейс IMFAsyncCallback. После использования MFCreateVideoSampleFromSurface вы запрашиваете интерфейс IMFTrackedSample и вызываете SetAllocator. Метод Invoke сообщит вам, когда поверхность свободна.

Как я должен вывести поверхность? Должен ли я использовать MFCreateVideoSampleFromSurface или MFCreateDXSurfaceBuffer?

Поскольку вы используете IDirectXVideoProcessorService-> CreateSurface, MFCreateVideoSampleFromSurface является правильным местом. Вы выводите поверхность через образец IMFS.

Проверьте этот проект:

MFNode

Под MFTDxva2Decoder и MFSkDxva2Renderer вы найдете некоторую обработку dxva2.

1

Другие решения

Самый простой способ получить образцы Media Foundation — это загрузить и установить «Microsoft Windows SDK для Windows 7 и .NET Framework 4» из http://www.microsoft.com/en-us/download/details.aspx?id=8279. Установите образцы и найдите их в «v7.1 / Samples / Multimedia / MediaFoundation».
Образцы Media Foundation предположительно находятся на сайте Microsoft Code Gallery, но я не смог их там найти. Образцы больше не включены в выпуски Windows SDK.

Примеры, которые имеют непосредственное отношение к вашему вопросу: вероятно, Decoder, DXVA_HD, DXVA2_VideoProc, EVRPresenter, MPEG1Source и topoedit.

Я больше не могу оказывать помощь, так как в настоящее время борюсь с некоторыми из тех же проблем.

0

По вопросам рекламы [email protected]