从字节数组创建IMFByteStream

时间:2017-09-29 16:28:28

标签: c++ ms-media-foundation

我正在尝试调整最初从Microsoft的MediaFoundation音频播放示例获取URL的方法,而不是从const char *数组中获取源。问题是,CreateObjectFromByteStream需要一个IMFByteStream,而不是一个const char *。我怎样才能得到我需要的东西?

// Create a media source from a byte stream
HRESULT CreateMediaSource(const byte *data, IMFMediaSource **ppSource)
{
    MF_OBJECT_TYPE ObjectType = MF_OBJECT_INVALID;

    IMFSourceResolver* pSourceResolver = NULL;
    IUnknown* pSource = NULL;

    // Create the source resolver.
    HRESULT hr = MFCreateSourceResolver(&pSourceResolver);
    if (FAILED(hr))
    {
        goto done;
    }

    // Use the source resolver to create the media source.

    // Note: For simplicity this sample uses the synchronous method to create 
    // the media source. However, creating a media source can take a noticeable
    // amount of time, especially for a network source. For a more responsive 
    // UI, use the asynchronous BeginCreateObjectFromURL method.
    hr = pSourceResolver->CreateObjectFromByteStream(data,
        NULL,                       // URL of the source.
        MF_RESOLUTION_MEDIASOURCE | MF_BYTESTREAM_CONTENT_TYPE,  // Create a source object.
        NULL,                       // Optional property store.
        &ObjectType,        // Receives the created object type. 
        &pSource            // Receives a pointer to the media source.
        );
    if (FAILED(hr))
    {
        goto done;
    }

    // Get the IMFMediaSource interface from the media source.
    hr = pSource->QueryInterface(IID_PPV_ARGS(ppSource));

done:
    SafeRelease(&pSourceResolver);
    SafeRelease(&pSource);
    return hr;
}

2 个答案:

答案 0 :(得分:0)

我找到了最简单的方法来创建临时文件并在其中写入* data。骇客,但对我来说足够好,如果需要,可以轻松地用自定义内存IMFByteStream实现代替。

所以代码将是这样的:

Byte data[] = {'a','b','c','d','e','f'};

HRESULT hr = S_OK;
hr = MFStartup(MF_VERSION);

IMFByteStream *stream = NULL;
hr = MFCreateTempFile(
    MF_ACCESSMODE_READWRITE, 
    MF_OPENMODE_DELETE_IF_EXIST, 
    MF_FILEFLAGS_NONE, 
    &stream
);

ULONG wroteBytes = 0;
stream->Write(data, sizeof(data), &wroteBytes);
stream->SetCurrentPosition(0);

// make sure that wroteBytes is equal with data length

答案 1 :(得分:0)

您可以使用 MFCreateMFByteStreamOnStream()IMFByteStream 创建 IStream,也可以使用 IStream 从字节数组创建和 SHCreateMemStream()。撰写本文时的文档位于 https://docs.microsoft.com/en-us/windows/win32/api/mfidl/nf-mfidl-mfcreatemfbytestreamonstreamhttps://docs.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-shcreatememstream

这是一个简单的例子:

// Generate a byte array
int sample_size = 0x100;
BYTE* sample_bytes = (BYTE*)malloc(sample_size)

// Create the IStream from the byte array
IStream* pstm = SHCreateMemStream(sample_bytes, sample_size);

// Create the IMFByteStream from the IStream
IMFByteStream* pibs = NULL;
MFCreateMFByteStreamOnStream(pstm, &pibs);

// Clean up time
if (pibs)
    pibs->Close();
if (pstm)
    pstm->Release();
if (sample_bytes)
    free(sample_bytes)

有一个 IStream 接口但没有一个字节数组接口似乎在 Microsoft API 中经常出现。谢天谢地,创建 IStream 很容易。