Windows Media Foundation: получение декодированных данных AAC


Я хочу использовать Windows Media Foundation для получения аудиоданных файла в кодировке AAC. Я понял, что правильный способ-объявить IMFSample*, где будет храниться один образец аудио. В VS2015 я вижу, что этот класс имеет метод getDouble (), но ничего об этом нет в документации MSDN.

Вот часть примера, которую я пытаюсь сделать:

    IMFSample *pSample(NULL);

    hr = m_pReader->ReadSample(
        MF_SOURCE_READER_FIRST_AUDIO_STREAM, // [in] DWORD dwStreamIndex,
        0,                                   // [in] DWORD dwControlFlags,
        NULL,                                // [out] DWORD *pdwActualStreamIndex,
        &dwFlags,                            // [out] DWORD *pdwStreamFlags,
        &timestamp,                          // [out] LONGLONG *pllTimestamp,
        &pSample);                           // [out] IMFSample **ppSample

Последний аргументpSample - это то, что я хочу.

Теперь я хочу получить двойной, плавающий или байтовый указатель на текущий декодированный образец данных.

Как это можно сделать?

Заранее благодарю.

1 2

1 ответ:

Сначала преобразуем выборку в буфер:

Microsoft::WRL::ComPtr<IMFMediaBuffer> mediaBuffer;
sample->ConvertToContiguousBuffer(&mediaBuffer)

Затем заблокируйте буфер, чтобы получить указатель на его внутренние элементы:

BYTE *audioData = nullptr;
DWORD sampleBufferLength = 0;
mediaBuffer->Lock(&audioData, nullptr, &sampleBufferLength);
// use audioData...
mediaBuffer->Unlock();

Чтобы указать, какой формат данных возвращается вам, используйте SetCurrentMediaType на вашем читателе (сделайте это один раз в начале)

    Microsoft::WRL::ComPtr<IMFMediaType> pPartialType;
    MFCreateMediaType(&pPartialType);
    pPartialType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio);
    pPartialType->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_Float);
    reader->SetCurrentMediaType(
        (DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM,
        NULL, pPartialType.Get());

И, пожалуйста, используйте умные указатели везде с MF, или вы войдете в мир боли. Microsoft::WRL::ComPtr<XXX> это твой друг! Я пропустил проверку HRESULTs в этом примере кода, но вы определенно захотите это сделать.