I want to use Windows Media Foundation to get the audio data of an AAC-encoded file. I figured out that the right way is to declare an IMFSample* where the single sample of the audio will be kept. In VS2015 I see that this class has a method getDouble(), but there is nothing about it in the MSDN documentation.
Here is the part of example I am trying to do:
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,
×tamp, // [out] LONGLONG *pllTimestamp,
&pSample); // [out] IMFSample **ppSample
The last argument pSample is what I want.
Now, I want to get double, float or byte pointer to the current decoded sample data.
How can this be done?
Thanks in advance.
First convert the sample to a buffer:
Microsoft::WRL::ComPtr<IMFMediaBuffer> mediaBuffer;
sample->ConvertToContiguousBuffer(&mediaBuffer)
Then lock the buffer to get a pointer to its internals:
BYTE *audioData = nullptr;
DWORD sampleBufferLength = 0;
mediaBuffer->Lock(&audioData, nullptr, &sampleBufferLength);
// use audioData...
mediaBuffer->Unlock();
To specify what the format of the data is returned to you use SetCurrentMediaType
on your reader (do this once at the beginning)
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());
And please use smart pointers everywhere with MF or you'll enter a world of pain. Microsoft::WRL::ComPtr<XXX>
is your friend! I've missed out checking the HRESULTs in this example code but you'll definitely want to do that.