2016-07-25 8 views
5

Я пытаюсь использовать MediaFoundation API для кодирования видео, но у меня возникают проблемы с нажатием образцов на SinkWriter.Использование Media Foundation для кодирования поверхностей Direct X

Я получаю кадры для кодирования через API дублирования рабочего стола. В итоге я получил ID3D11Texture2D с изображением рабочего стола.

Я пытаюсь создать IMFVideoSample, содержащий эту поверхность, а затем нажимать этот образец видео на SinkWriter.

Я пытался идти об этом по-разному:

  • Я назвал MFCreateVideoSampleFromSurface(texture, &pSample) где текстура является ID3D11Texture2D, заполненный в SampleTime и SampleDuration, а затем передает созданный образец в SinkWriter.
    SinkWriter вернулся E_INVALIDARG.

  • Я попытался создать образец, передав nullptr в качестве первого аргумента и создав сам буфер, используя MFCreateDXGISurfaceBuffer, а затем передав результирующий буфер в Sample.
    Это тоже не сработало.

  • Я прочитал документацию MediaFoundation и не смог найти подробную информацию о том, как создать образец из текстуры DirectX.

У меня кончились вещи, чтобы попробовать.
Кто-нибудь там использовал этот API раньше и может думать о вещах, которые я должен проверить, или о том, как я могу отлаживать это?

+0

Я думаю, что вы допустили ошибку при использовании 'MFCreateVideoSampleFromSurface' и' MFCreateDXGISurfaceBuffer'.Эти функции создают буферы для записи на поверхность DirectX и визуализации, и они создают объекты с интерфейсом 'IMF2DBuffer', но кодеры и писатели нуждаются в объектах с' IMFMediaBuffer'. Они не могут понять 'IMF2DBuffer'. Попробуйте использовать функцию «MFCreateSampleCopierMFT» - он создал объект MFT для копирования из 'IMFMediaBuffer' в' IMF2DBuffer' на [MSDN] (https://msdn.microsoft.com/en-us/library/windows/desktop/dd388101 (v = vs.85) .aspx). Может быть, это может сделать вспять работу!?! –

+0

Вы уверены? Рассматривая документацию для 'MFCreateDXGISurfaceBuffer', она заявляет, что возвращает указатель на IMFMediaBuffer. –

+0

Вы можете попробовать получить данные через буфер 'IMFMediaBuffer' из' MFCreateDXGISurfaceBuffer'. –

ответ

1

Прежде всего, вы должны научиться использовать mftrace tool. Скорее всего, он сразу скажет вам о проблеме.

Но я предполагаю, что возможны следующие проблемы.

  1. Возможно, некоторые другие атрибуты необходимы помимо SampleTime/SampleDuration.

  2. Возможно, SinkWriter нуждается в текстуре, которую он может читать на процессоре. Чтобы исправить это, когда доступен кадр, создайте промежуточную текстуру того же формата + размер, вызовите CopyResource, чтобы скопировать рабочий стол в промежуточную текстуру, а затем передать эту промежуточную текстуру в MF.

  3. Даже если вы используете аппаратный кодер, поэтому процессор никогда не пытается прочитать данные текстуры, я не думаю, что это хорошая идея, чтобы напрямую передать текстуру вашего рабочего стола в MF.

Когда вы устанавливаете текстуру D3D для образца, данные не копируются нигде, образец просто сохраняет текстуру.

MF работает асинхронно, он может буферизовать несколько выборок в своих узлах топологии, если они этого захотят.

DD дает вам данные синхронно, вы можете получить доступ только к тексту между вызовами AcquireNextFrame и ReleaseFrame.

+0

Я старался не путать вопрос со слишком большим количеством деталей, но я копирую текстуру рабочего стола, прежде чем передавать его в MF, получив дескриптор дескриптора рабочего стола и создав новую текстуру, используя это перед использованием CopyResource. Но спасибо за указатель mftrace, посмотрим на это. –

+0

Я использовал mfctrace и понял, что образцы, отправляемые в раковину, сообщаются как имеющие размер 0B, поэтому что-то не так с их созданием. –