如何读取-"unsigned char const *"什么时候使用Media Foundation? [英] How to read from - "unsigned char const *" when use Media Foundation?
问题描述
我有这样的实现
void coAudioPlayerSampleGrabber::test(SoundDataType dataType,
unsigned char const * pData,
int64_t dataLen)
{
HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0);
IMFSourceReader *pReader = NULL;
IMFByteStream * spByteStream = NULL;
HRESULT hr = S_OK;
// Initialize the COM library.
hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
// Initialize the Media Foundation platform.
if (SUCCEEDED(hr))
{
hr = MFStartup(MF_VERSION);
}
hr = MFCreateMFByteStreamOnStreamEx((IUnknown*)pData, &spByteStream);
if (FAILED(hr))
{
printf("Error MFCreateMFByteStreamOnStreamEx");
}
IMFAttributes * Atrr = NULL;
hr = MFCreateAttributes(&Atrr, 10);
if (FAILED(hr))
{
printf("Error MFCreateAttributes");
}
hr = Atrr->SetUINT32(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, true);
if (FAILED(hr))
{
printf("Error Atrr->SetUINT32(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, true)");
}
hr = MFCreateSourceReaderFromByteStream(spByteStream, Atrr, &pReader);
if (FAILED(hr))
{
printf("Error MFCreateSourceReaderFromByteStream");
}
if (FAILED(hr))
{
printf("Error opening input file");
}
IMFMediaType *pAudioType = NULL; // Represents the PCM audio format.
hr = ConfigureAudioStream(dataType, pReader, &pAudioType);
if (FAILED(hr))
{
printf("Error ConfigureAudioStream");
}
IMFSample *pSample = NULL;
IMFMediaBuffer *pBuffer = NULL;
BYTE *pAudioData = NULL;
DWORD cbBuffer = 0;
std::vector<SampleData> samples_vec;
while (true)
{
DWORD dwFlags = 0;
hr = pReader->ReadSample((DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM, 0, NULL, &dwFlags, NULL, &pSample);
if (FAILED(hr)) { break; }
if (dwFlags & MF_SOURCE_READERF_CURRENTMEDIATYPECHANGED)
{
printf("Type change - not supported by WAVE file format.\n");
break;
}
if (dwFlags & MF_SOURCE_READERF_ENDOFSTREAM)
{
printf("End of input file.\n");
break;
}
hr = pSample->ConvertToContiguousBuffer(&pBuffer);
if (FAILED(hr)) { break; }
hr = pBuffer->Lock(&pAudioData, NULL, &cbBuffer);
if (FAILED(hr)) { break; }
//Do something with the pAudioData which is an array of unsigned chars of lenth cbBuffer
SampleData tmp;
tmp.pAudioData = new byte[cbBuffer];
memcpy(tmp.pAudioData, pAudioData, cbBuffer);
tmp.cbBuffer = cbBuffer;
samples_vec.push_back(tmp);
// Unlock the buffer.
hr = pBuffer->Unlock();
pAudioData = NULL;
if (FAILED(hr)) { break; }
}
SafeRelease(&pReader);
SafeRelease(&pSample);
SafeRelease(&pBuffer);
SafeRelease(&spByteStream);
SafeRelease(&Atrr);
// Shut down Media Foundation.
MFShutdown();
CoUninitialize();
}
因此,如您所见,我有指向数据和大小的指针,实际上这是我需要对它进行解码的数据.问题是这里
So as you can see I have pointer to data and size this is actually my data I need to decode it. Problem is that here
hr = MFCreateMFByteStreamOnStreamEx((IUnknown*)pData, &spByteStream);
我遇到错误访问冲突
,据我所知,这是因为我尝试将 pData
转换为 IUnknown *
.问题是-如何正确转换?
I got an error access violation
and as far as I see this is because I try to convert pData
to IUnknown*
. Question is - How to convert it right?
推荐答案
您不能像这样偷工减料:
You can't cut corners like this:
unsigned char const * pData;
...
hr = MFCreateMFByteStreamOnStreamEx((IUnknown*)pData, &spByteStream);
IUnknown
还是一个字节的别称.如所记录的,您应该从字面上提供表示流的接口指针.
IUnknown
is not yet another fancy alias for a byte. You are supposed to literally supply interface pointer representing stream, as documented.
Media Foundation确实为您提供了读取内存字节的方法.您需要根据文档创建一个创建真实流的 IStream
或 IRandomAccessStream
或 IMFByteStream
.还提供您使用适当的属性创建的 IMFAttributes
以指定数据类型(否则,如果文件是从扩展名或MIME类型派生的),则Source Reader API将能够处理内存字节作为源媒体文件数据,然后合适的解码器会将音频解码为PCM数据(类似于此).
Media Foundation does offer you means to read from memory bytes. You need to create a create a real stream, IStream
or IRandomAccessStream
or IMFByteStream
per docuemntation. Also supply IMFAttributes
you created with proper attributes to specify data type (which otherwise in the case of a file are derived from extension or MIME type) and then Source Reader API would be able to process memory bytes as source of media file data, and suitable decoder would decode audio into PCM data (similar to this).
您可以快速完成以下操作: CreateStreamOnHGlobal
创建 IStream
实现并将您的字节复制到基础缓冲区中(请参阅文档).然后 MFCreateMFByteStreamOnStream
会在其上创建一个 IMFByteStream
包装,您可以将此包装用作 MFCreateSourceReaderFromByteStream
参数.
Something you can do real quick: CreateStreamOnHGlobal
to create IStream
implementation and copy your bytes into underlying buffer (see docs). Then MFCreateMFByteStreamOnStream
would create a IMFByteStream
wrappr over it, and you can use this wrapper as MFCreateSourceReaderFromByteStream
argument.
这篇关于如何读取-"unsigned char const *"什么时候使用Media Foundation?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!