How to create IMFSample for WindowsMediaFoundation

2019-05-31 23:46发布

问题:

I'm learning to use the H.264 encoder in Windows Media Foundation.

What I currently have are media samples in YUV420p format, so that's buffers containing YYYYYYYYUUVV data.

Since the H.264 encoder MFT requires input in form of IMFSample, I'm not sure how to convert the data in buffer into IMFSample.

May I just do like this:

IMFMediaBuffer *pBuffer = NULL;
MFCreateMemoryBuffer(cbSize, &pBuffer);
BYTE *pData = NULL;
pBuffer->Lock(&pData, NULL, NULL);
memcpy(pData, bufferIhaveinYYYYUV format, buffer size); // is it correct?
pBuffer->Unlock();
IMFSample *pSample = NULL;
MFCreateSample(&pSample);
pSample->AddBuffer(pBuffer);

Thanks

回答1:

This is how I do it (full example at https://github.com/sipsorcery/mediafoundationsamples/blob/master/MFMP4ToYUVWithMFT/MFMP4ToYUVWithMFT.cpp):

IMFMediaBuffer *srcBuf = NULL;
DWORD srcBufLength;
byte *srcByteBuffer;
DWORD srcBuffCurrLen = 0;
DWORD srcBuffMaxLen = 0;
CHECK_HR(videoSample->ConvertToContiguousBuffer(&srcBuf), "ConvertToContiguousBuffer failed.\n");
CHECK_HR(srcBuf->GetCurrentLength(&srcBufLength), "Get buffer length failed.\n");
CHECK_HR(srcBuf->Lock(&srcByteBuffer, &srcBuffMaxLen, &srcBuffCurrLen), "Error locking source buffer.\n");

//// Now re-constuct.
MFCreateSample(&reConstructedVideoSample);
CHECK_HR(MFCreateMemoryBuffer(srcBufLength, &reConstructedBuffer), "Failed to create memory buffer.\n");
CHECK_HR(reConstructedVideoSample->AddBuffer(reConstructedBuffer), "Failed to add buffer to re-constructed sample.\n");
CHECK_HR(reConstructedVideoSample->SetSampleTime(llVideoTimeStamp), "Error setting the recon video sample time.\n");
CHECK_HR(reConstructedVideoSample->SetSampleDuration(llSampleDuration), "Error setting recon video sample duration.\n");

byte *reconByteBuffer;
DWORD reconBuffCurrLen = 0;
DWORD reconBuffMaxLen = 0;
CHECK_HR(reConstructedBuffer->Lock(&reconByteBuffer, &reconBuffMaxLen, &reconBuffCurrLen), "Error locking recon buffer.\n");
memcpy(reconByteBuffer, srcByteBuffer, srcBuffCurrLen);
CHECK_HR(reConstructedBuffer->Unlock(), "Error unlocking recon buffer.\n");
reConstructedBuffer->SetCurrentLength(srcBuffCurrLen);