Декодер Windows MFT (Media Foundation Transform) не возвращает правильное время выборки или длительность

Чтобы декодировать поток H264 с помощью базового преобразования Windows Media, рабочий процесс в настоящее время выглядит примерно так:

IMFSample sample;
sample->SetTime(time_in_ns);
sample->SetDuration(duration_in_ns);
sample->AddBuffer(buffer);

// Feed IMFSample to decoder
mDecoder->ProcessInput(0, sample, 0);

// Get output from decoder.
/* create outputsample that will receive content */ { ... }
MFT_OUTPUT_DATA_BUFFER output = {0};
output.pSample = outputsample;
DWORD status = 0;
HRESULT hr = mDecoder->ProcessOutput(0, 1, &output, &status);
DWORD status = 0;
hr = mDecoder->ProcessOutput(0, 1, &output, &status);
if (output.pEvents) {
// We must release this, as per the IMFTransform::ProcessOutput()
// MSDN documentation.
output.pEvents->Release();
output.pEvents = nullptr;
}

if (hr == MF_E_TRANSFORM_STREAM_CHANGE) {
// Type change, probably geometric aperture change.
// Reconfigure decoder output type, so that GetOutputMediaType()
} else if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) {
// Not enough input to produce output.
} else if (!output.pSample) {
return S_OK;
} else }
// Process output
}

}

Когда мы передали все данные в MFT-декодер, мы должны истощить его:

mDecoder->ProcessMessage(MFT_MESSAGE_COMMAND_DRAIN, 0);

Теперь одна вещь, связанная с декодером WMF H264, заключается в том, что он обычно ничего не выводит до вызова с более чем 30 сжатыми кадрами h264 независимо от размера скользящего окна h264. Задержка очень высокая …

Я столкнулся с проблемой, которая очень хлопотна.
С видео, состоящим только из ключевых кадров и имеющим только 15 кадров, каждый из которых имеет длину 2 с, причем первый кадр имеет ненулевое время представления (этот поток из живого контента, поэтому первый кадр обычно находится во времени эпоса)
Поэтому, не истощая декодер, из декодера ничего не выйдет, так как он не получил достаточно кадров.

Тем не менее, после того, как декодер слит, декодированный кадр выйдет. ОДНАКО, MFT-декодер установил все длительности только на 33,6 мс, а время представления первого сэмпла всегда равно 0.
Первоначальная продолжительность и время представления были потеряны.

Если вы предоставите более 30 кадров для декодера h264, то действительны как длительность, так и число точек …

Я еще не нашел способ заставить декодер WMF выводить образцы с правильным значением.
Похоже, что если вам нужно слить декодер до того, как он сам выдаст какие-либо сэмплы, то он полностью сломан …

Кто-нибудь сталкивался с такими проблемами? Как ты справился с этим?

заранее спасибо

Изменить: образец видео доступен на http://people.mozilla.org/~jyavenard/mediatest/fragmented/1301869.mp4
Воспроизведение этого видео с Firefox приведет к его очень быстрому воспроизведению из-за проблем, описанных выше.

2

Решение

Я не уверен, что ваш рабочий процесс правильный. Я думаю, что вы должны сделать что-то вроде этого:

do
{
...
hr = mDecoder->ProcessInput(0, sample, 0);
if(FAILED(hr))
break;
...
hr = mDecoder->ProcessOutput(0, 1, &output, &status);
if(FAILED(hr) && hr != MF_E_TRANSFORM_NEED_MORE_INPUT)
break;
}
while(hr == MF_E_TRANSFORM_NEED_MORE_INPUT);

if(SUCCEEDED(hr))
{
// You have a valid decoded frame here
}

Идея состоит в том, чтобы продолжать вызывать ProcessInput / ProcessOuptut, пока ProcessOutput возвращает MF_E_TRANSFORM_NEED_MORE_INPUT. MF_E_TRANSFORM_NEED_MORE_INPUT означает, что декодеру требуется больше ввода. Я думаю, что с этим циклом вам не нужно будет сливать декодер.

1

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

Других решений пока нет …

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