Утечка памяти в функции Windows Media Foundation MFCreateSourceReaderFromURL. Какие-нибудь альтернативные функции? - PullRequest
0 голосов
/ 08 октября 2019

В Windows 10 есть ошибка в функции Windows Media Foundation (MFCreateSourceReaderFromURL). Это вызывает утечку памяти после каждого использования. Есть ли альтернативные функции для использования без утечки памяти? Кажется, Windows Media Foundation полна ошибок, так как я могу избежать этого?

Докажите утечку памяти, запустите этот код (x86) и наблюдайте огромную утечку памяти каждую секунду:

#include <mfapi.h>
#include <mfidl.h>
#include <mfreadwrite.h>
#pragma comment (lib, "Mfreadwrite.lib")
#pragma comment (lib, "Mfplat.lib")
#pragma comment (lib, "mfuuid.lib")

int main()
{
    while (true)
    {
        if (FAILED(CoInitializeEx(NULL, COINIT_MULTITHREADED)))
        {
            return 1;
        }
        if (FAILED(MFStartup(MF_VERSION)))
        {
            return 1;
        }
        IMFSourceReader* sourceReader = nullptr;
        if (FAILED(MFCreateSourceReaderFromURL(L"C:/any_audio_file.wav", nullptr, &sourceReader)))
        {
            return 1;
        }
        sourceReader->Release();
        MFShutdown();
        CoUninitialize();
    }
    return 0;
}

Оффтоп: так расстроен. Я использовал DirectShow только для обнаружения ошибки в сетевом аудиопотоке RenderFile. Через несколько дней перешел на альтернативу (Windows Media Foundation) и обнаружил, что там утечка памяти. Microsoft f *** you.

Редактировать: утечка памяти происходит только в том случае, если имя файла не имеет * .mp3 в конце (а содержимое - mp3). Или, если имя файла не имеет * .wav в конце (а содержимое - волна). Пример: есть mp3-файл «music.mp3». Измените имя на «music» или «music.wav». Произойдет утечка памяти.

Ответы [ 2 ]

0 голосов
/ 14 ноября 2019

Основываясь на коде, вы вызывали API MFShutdown и CoUninitialize несколько раз в одном потоке. Эти два API должны вызываться только один раз для каждого потока.

Ниже приведен модифицированный код, который соответствует более реальному сценарию использования. Вы можете построить этот код как release (не отладочный) и запустить его, и вы увидите, что за 60 секунд объем памяти увеличивается незначительно (150 кб). Небольшое увеличение связано с увеличением размера кэша DLL (ожидается) и увеличением числа создаваемых рабочих очередей (ожидается). Итак, в настоящее время я не вижу никаких признаков утечки памяти.

if (FAILED(CoInitializeEx(NULL, COINIT_MULTITHREADED))) // <- Should only be called once per thread
{
    return 1;
}
if (FAILED(MFStartup(MF_VERSION))) // <- Should only be called once per thread
{
    return 1;
}

while (true)
{
    IMFSourceReader* sourceReader = nullptr;

    OutputDebugString(L"MFCreateSourceReaderFromURL \r\n");

    if (FAILED(MFCreateSourceReaderFromURL(L"maybe-next-time", nullptr, &sourceReader)))
    {
        return 1;
    }

    sourceReader->Release();

    Sleep(100); // <- Make sure to yield the processor before continuing with the loop 
}

MFShutdown(); // <- Should only be called once per thread
CoUninitialize(); // <- Should only be called once per thread

Если утечка памяти с вашей стороны не вызвана этим, не могли бы вы поделиться примером кода, который может представлять реальное использование слова?

0 голосов
/ 08 октября 2019

Это ошибка в Microsoft Windows Media Foundation. Это также было подтверждено в комментариях.

Решение:

Не используйте Microsoft Windows Media Foundation в профессиональном программном обеспечении, поскольку оно полно скрытых ошибок и утечек памяти.

...