The byte stream type of the given URL is unsupported MediaFoundation

喜欢而已 提交于 2021-01-07 07:01:52

问题


I need to create a reader from buffer(that is wav bytes) in order to do it I am using such approach:

void co_AudioEncoderMF::load_from_memory(unsigned char const * data, long data_size)
{
    unsigned char * buf = new unsigned char[data_size]; //JUST FOR TEST IN ORDER TO BE SURE THAT I HAVE THIS DATA
    memcpy(buf, data, data_size);

    IMFMediaType *input_type = nullptr;
    IMFSourceReader *source_reader = nullptr;
    IMFMediaType *ouput_media_type = nullptr;
    IMFSinkWriter *sink_writer = nullptr;
    IStream * stream = nullptr;
    IMFByteStream * byte_stream = nullptr;

    HRESULT hr = InitAndStartCOMLib();

    if (SUCCEEDED(hr))
    {
        hr = create_stream(buf, data_size, &stream);  <---- HERE I CREATE A STREAM
    }

    if (SUCCEEDED(hr))
    {
        hr = MFCreateMFByteStreamOnStream(stream, &byte_stream);
    }

    HGLOBAL hGlobal = nullptr;
    //IMFSourceReader *pReader = nullptr;

    if (SUCCEEDED(hr))
    {
        GetHGlobalFromStream(stream, &hGlobal);
        hr = create_source_reader(byte_stream, &source_reader);   <----- HERE I CREATE A READER
    }
...
}
HRESULT co_AudioEncoderMF::InitAndStartCOMLib()
{
    HRESULT hr = S_OK;
    HeapSetInformation(nullptr, HeapEnableTerminationOnCorruption, nullptr, 0);

    // Initialize the COM library.
    hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);

    // Initialize the Media Foundation platform.
    if (SUCCEEDED(hr))
    {
        hr = MFStartup(MF_VERSION);
    }

    return hr;
}
HRESULT co_AudioEncoderMF::create_stream(unsigned char const * pData, long dataLen, IStream ** out_stream)
{
    HGLOBAL m_phMem = ::GlobalAlloc(GMEM_MOVEABLE, dataLen);

    if (!m_phMem)
    {
        printf("Error AfxThrowMemoryException");
    }

    LPVOID dest = ::GlobalLock(m_phMem);

    memcpy(dest, pData, dataLen);
    ::GlobalUnlock(m_phMem);

    return CreateStreamOnHGlobal(m_phMem, FALSE /*fDeleteOnRelease*/, out_stream);// NOTE :: in order to get more flexablity need to consider such an approach https://gist.github.com/alekseytimoshchenko/e8f52604fdeb50c8ad7873aeb8281bfa
}
HRESULT co_AudioEncoderMF::create_source_reader(IMFByteStream * in_byte_stream, IMFSourceReader **source_reader)
{
    HRESULT hr = S_OK;

    IMFAttributes * attr = nullptr;
    hr = MFCreateAttributes(&attr, 10);

    if (SUCCEEDED(hr))
    {
        hr = attr->SetUINT32(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, true);
    }
    else
    {
        printf("Error MFCreateAttributes");
    }

    if (SUCCEEDED(hr))
    {
        hr = MFCreateSourceReaderFromByteStream(in_byte_stream, attr, source_reader); <----- AND HERE I GOT MY ERROR ABOUT UNSUPPORTED FORMAT
    }
    else
    {
        printf("Error Atrr->SetUINT32(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, true)");
    }

    if (FAILED(hr))
    {
        printf("Error MFCreateSourceReaderFromByteStream");
    }

    return hr;
}

I am using the same approach but with mp3 bytes and it is works, I assume that it has a difference, but I don't know how to approve it and solve.


回答1:


In my case problem was in that I tried to call this method MFCreateSourceReaderFromByteStream on stream that was created on wav bytes, but it didn't includes .wav header. So, I was needed to add a header. I used this method

/*static*/ void Utils::append_data_to_wav_header(unsigned char * buff, int buff_size, int num_of_channels, int sample_rate, std::vector<unsigned char> & out_buf)
{
    //*** START OF HEADER
    long idx = 0;
    uint32_t uint_32_buf = buff_size + 44 /*header size*/;

    out_buf.resize(uint_32_buf);
    std::string str_buf = "RIFF";
    memcpy(&out_buf[idx], str_buf.c_str(), strlen(str_buf.c_str()));
    idx += (long)strlen(str_buf.c_str());

    memcpy(&out_buf[idx], &uint_32_buf, sizeof(uint_32_buf));
    idx += sizeof(uint_32_buf);

    str_buf = "WAVE";
    memcpy(&out_buf[idx], str_buf.c_str(), strlen(str_buf.c_str()));
    idx += (long)strlen(str_buf.c_str());

    str_buf = "fmt ";
    memcpy(&out_buf[idx], str_buf.c_str(), strlen(str_buf.c_str()));
    idx += (long)strlen(str_buf.c_str());

    uint_32_buf = 16;
    memcpy(&out_buf[idx], &uint_32_buf, 1);
    idx += sizeof(uint_32_buf);

    uint16_t uint_16_buff = 1;
    memcpy(&out_buf[idx], &uint_16_buff, 1);
    idx += sizeof(uint_16_buff);

    uint_16_buff = num_of_channels;
    memcpy(&out_buf[idx], &uint_16_buff, 1);
    idx += sizeof(uint_16_buff);

    uint_32_buf = sample_rate;
    memcpy(&out_buf[idx], &uint_32_buf, 1);
    idx += sizeof(uint_32_buf);

    uint_32_buf = (sample_rate * 16 * num_of_channels) / 8;
    memcpy(&out_buf[idx], &uint_32_buf, 1);
    idx += sizeof(uint_32_buf);

    uint_16_buff = 16 * num_of_channels / 8;
    memcpy(&out_buf[idx], &uint_16_buff, 1);
    idx += sizeof(uint_16_buff);

    uint_16_buff = 16;
    memcpy(&out_buf[idx], &uint_16_buff, 1);
    idx += sizeof(uint_16_buff);

    str_buf = "data";
    memcpy(&out_buf[idx], str_buf.c_str(), strlen(str_buf.c_str()));
    idx += (long)strlen(str_buf.c_str());

    uint_32_buf = buff_size;
    memcpy(&out_buf[idx], &uint_32_buf, 1);
    idx += sizeof(uint_32_buf);
    //*** END OF HEADER

    memcpy(&out_buf[idx], buff, buff_size);
    idx += buff_size;
}


来源:https://stackoverflow.com/questions/65426136/the-byte-stream-type-of-the-given-url-is-unsupported-mediafoundation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!