如何读取-"unsigned char const *"什么时候使用Media Foundation? [英] How to read from - "unsigned char const *" when use Media Foundation?

查看:174
本文介绍了如何读取-"unsigned char const *"什么时候使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆