Тип потока байтов для данного URL-адреса не поддерживается MediaFoundation

Мне нужно создать ридер из буфера (то есть байтов wav), чтобы сделать это, я использую такой подход:

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, и он работает, я предполагаю, что он имеет разницу, но я не знаю, как это одобрить и решить.

Что такое «байты WAV»? Это содержимое действительного и воспроизводимого файла .WAV или что-то еще? Файл .WAV должен работать.

Roman R. 23.12.2020 16:28

@РоманР. на самом деле в моем случае проблема заключалась в том, что .wav данные не включали заголовок. Опубликовал мой ответ, возможно, поможет. В любом случае, спасибо, потому что сначала я не был уверен, что смогу создать ридер на wav, но после того, как вы подтвердили, что это не должно быть проблемой, я начал проверять формат wav.

Sirop4ik 24.12.2020 09:08
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
955
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В моем случае проблема заключалась в том, что я пытался вызвать этот метод MFCreateSourceReaderFromByteStream в потоке, который был создан на байтах wav, но он не включал заголовок .wav. Итак, мне нужно было добавить заголовок. Я использовал этот метод

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

Другие вопросы по теме