MF SinkWriter Speicherprobleme

Ich versuche, Bilder meines Desktops (1920 x 1080) mit der DXGI Desktop Duplication API und MF Sink Writer in eine Videodatei zu kodieren. Mein Codierungsthread sieht folgendermaßen aus:

#define RETURN_ON_BAD_HR(expr) \
{ \
    HRESULT _hr_ = (expr); \
    if (FAILED(_hr_)) { \
        qDebug() << "Error encountered with message from HRESULT: " << \
                    getMessageFromHR(_hr_); \
        MFShutdown(); \
        CoUninitialize(); \
        return; \
    } \
}

void DuplicationThread::run() {
    if (CoInitializeEx(NULL, COINIT_APARTMENTTHREADED) != S_OK) {
        qDebug() << "Failed to initialize COM.";
        return;
    }

    if (MFStartup(MF_VERSION) != S_OK) {
        qDebug() << "Failed to initialize Media Foundation.";
        CoUninitialize();
        return;
    }

    CComPtr<ID3D11Device> pDevice;
    RETURN_ON_BAD_HR(InitializeDx(&pDevice));

    CComPtr<IDXGIOutputDuplication> pDeskDupl;
    RETURN_ON_BAD_HR(InitiateDupl(pDevice, &pDeskDupl));

    CComPtr<IMFSinkWriter> pSinkWriter;
    DWORD streamIndex;
    RETURN_ON_BAD_HR(InitSinkWriter(&pSinkWriter, &streamIndex));

    LONGLONG rtStart = 0;

    while (!isInterruptionRequested()) {
        DXGI_OUTDUPL_FRAME_INFO frameInfo;
        CComPtr<IDXGIResource> pDesktopResource;
        RETURN_ON_BAD_HR(pDeskDupl->AcquireNextFrame(500, &frameInfo, &pDesktopResource));

        CComPtr<ID3D11Texture2D> pAcquiredDesktopImage;
        RETURN_ON_BAD_HR(pDesktopResource->QueryInterface(__uuidof(ID3D11Texture2D), reinterpret_cast<void **>(&pAcquiredDesktopImage)));

        CComPtr<IMFMediaBuffer> pMediaBuffer;
        RETURN_ON_BAD_HR(MFCreateDXGISurfaceBuffer(__uuidof(ID3D11Texture2D), pAcquiredDesktopImage, 0, FALSE, &pMediaBuffer));

        CComPtr<IMF2DBuffer> p2DBuffer;
        DWORD length;
        RETURN_ON_BAD_HR(pMediaBuffer->QueryInterface(__uuidof(IMF2DBuffer), reinterpret_cast<void **>(&p2DBuffer)));
        RETURN_ON_BAD_HR(p2DBuffer->GetContiguousLength(&length));
        RETURN_ON_BAD_HR(pMediaBuffer->SetCurrentLength(length));

        CComPtr<IMFSample> pSample;
        RETURN_ON_BAD_HR(MFCreateVideoSampleFromSurface(NULL, &pSample));
        RETURN_ON_BAD_HR(pSample->AddBuffer(pMediaBuffer));
        RETURN_ON_BAD_HR(pSample->SetSampleTime(rtStart));
        RETURN_ON_BAD_HR(pSample->SetSampleDuration(VIDEO_FRAME_DURATION));

        RETURN_ON_BAD_HR(pSinkWriter->WriteSample(streamIndex, pSample));
        RETURN_ON_BAD_HR(pDeskDupl->ReleaseFrame());
        rtStart += VIDEO_FRAME_DURATION;

        // successful iterations 
        static int count = 0;
        qDebug() << "count: " << count++;
    }

    RETURN_ON_BAD_HR(pSinkWriter->Finalize());

    MFShutdown();
    CoUninitialize();
}

Initialisierungsroutinen werden direkt von @ übernommDesktop Duplication Sample undSink Writer Tutorial. Die Definition des Videoformats stammt ebenfalls aus dem Sink Writer-Lernprogramm, mit Änderungen an der Bildauflösung undVIDEO_INPUT_FORMAT = MFVideoFormat_ARGB32.

Nach ca. 20-maligem Durchlaufen dieser Schleife (manchmal ein bisschen mehr, manchmal ein bisschen weniger) tritt jedoch entweder ein Fehler aufmSinkWriter->WriteSample() odermDeskDupl->AcquireNextFrame() mit der folgenden HRESULT-Nachricht:

Die Anwendung hat einen ungültigen Anruf getätigt. Entweder waren die Parameter des Aufrufs oder der Status eines Objekts falsch. Aktivieren Sie die D3D-Debug-Ebene, um Details über Debug-Meldungen anzuzeigen.

Wenn die D3D-Debug-Ebene aktiviert ist, sehe ich, dass meine Frames (ich nehme an, diese Objekte sind meine Frames) aus irgendeinem Grund nicht freigegeben wurden und stapeln sich einfach weiter auf:

D3D11 WARNUNG: Live-Objekt um 0x0000006504FFC290, Refcount: 17. [STATE_CREATION WARNUNG # 0: UNBEKANNT]

Ich bin mir ziemlich sicher, dass HRESULT-Fehler darauf zurückzuführen sind, dass meiner GPU der Speicher ausgeht (dies wird auch durch das Überwachen der GPU-Speichernutzung mit dem GPU-Z-Dienstprogramm bestätigt). Ich habe jedoch keine Ahnung, was diesen Speicherverlust verursacht, da ich jede von mir zugewiesene Ressource freigebe SafeRelease Implementierung).

BEARBEITEN Geänderte Zeiger zu intelligenten Zeigern und hinzugefügte Makrodefinition.

Antworten auf die Frage(0)

Ihre Antwort auf die Frage