Реализация 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. Я не смог ничего найти...

Спасибо

2 ответа

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

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

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

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

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

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

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

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

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

MFNode

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

Самый простой способ получить образцы 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.

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

Другие вопросы по тегам