给定URL的字节流类型是不受支持的MediaFoundation [英] The byte stream type of the given URL is unsupported MediaFoundation

查看:119
本文介绍了给定URL的字节流类型是不受支持的MediaFoundation的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要从缓冲区(即 wav字节)创建一个读取器,以便使用此方法:

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;
}

我使用相同的方法,但使用mp3字节,并且可以使用,我认为它有所不同,但是我不知道如何批准和解决.

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.

推荐答案

就我而言,问题是我尝试在基于wav字节创建的流上调用此方法 MFCreateSourceReaderFromByteStream 包括 .wav 标头.因此,需要添加一个标题.我用这种方法

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;
}

这篇关于给定URL的字节流类型是不受支持的MediaFoundation的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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