NVidia sample AppEncD3D11 leaking memory since driver 440.97 has been released

Hello,

I am trying to launch your sample AppEncD3D11 from this link: https://developer.nvidia.com/nvidia-video-codec-sdk.

I am running this sample in Windows 10 x64.
I edited the sample to only initialize DXGI and encoder in a loop.

int main(int argc, char** argv)
{
    /// The app will try to capture 60 times, by default
    int nFrames = 60;
    int ret = 0;
    bool useNvenc = true;

    /// all parsing arguments code
    
    /// Kick off the demo

    while (true) {
        ret = Grab60FPS(nFrames);
    }
    return ret;
}

And I commented the code about duplication and colors.

//main.cpp

/// Initialize demo application
HRESULT Init()
{
    HRESULT hr = S_OK;

    hr = InitDXGI();
    returnIfError(hr);

    hr = InitEnc();
    returnIfError(hr);

    return hr;
}

/// Demo 60 FPS (approx.) capture
int Grab60FPS(int nFrames)
{
    DemoApplication Demo;
    HRESULT hr = S_OK;

    /// Initialize Demo app
    hr = Demo.Init();
    if (FAILED(hr))
    {
        printf("Initialization failed with error 0x%08x\n", hr);
        return -1;
    }

    Sleep(1000);
    return 0;
}

Using drivers like 436.48 or older, everything goes well and the program uses around 165MB of process memory.

The problem is that using the driver 440.97 or newer, there is a huge leak of memory. Around 30MB are leaked for every iteration of the loop.

Did you notice it ? Is there any workaround to release properly all resources and thus avoiding this leak ?

EDIT:
It appears that “nvEncRegisterResource” function from the NvAPI adds reference on the ID3D11Device which is not released when “nbEncUnregisteredResource” is called.

// NvEncoderD3D11.cpp

void NvEncoder::RegisterResources(std::vector<void*> inputframes, NV_ENC_INPUT_RESOURCE_TYPE eResourceType,
                                         int width, int height, int pitch, NV_ENC_BUFFER_FORMAT bufferFormat, bool bReferenceFrame)
{
    for (uint32_t i = 0; i < inputframes.size(); ++i)
    {
        NV_ENC_REGISTER_RESOURCE registerResource = { NV_ENC_REGISTER_RESOURCE_VER };
        registerResource.resourceType = eResourceType;
        registerResource.resourceToRegister = (void *)inputframes[i];
        registerResource.width = width;
        registerResource.height = height;
        registerResource.pitch = pitch;
        registerResource.bufferFormat = bufferFormat;

        // a reference is added on m_pDevice here
        NVENC_API_CALL(m_nvenc.nvEncRegisterResource(m_hEncoder, &registerResource));

        std::vector<uint32_t> _chromaOffsets;
        NvEncoder::GetChromaSubPlaneOffsets(bufferFormat, pitch, height, _chromaOffsets);
        NvEncInputFrame inputframe = {};
        inputframe.inputPtr = (void *)inputframes[i];
        inputframe.chromaOffsets[0] = 0;
        inputframe.chromaOffsets[1] = 0;
        for (uint32_t ch = 0; ch < _chromaOffsets.size(); ch++)
        {
            inputframe.chromaOffsets[ch] = _chromaOffsets[ch];
        }
        inputframe.numChromaPlanes = NvEncoder::GetNumChromaPlanes(bufferFormat);
        inputframe.pitch = pitch;
        inputframe.chromaPitch = NvEncoder::GetChromaPitch(bufferFormat, pitch);
        inputframe.bufferFormat = bufferFormat;
        inputframe.resourceType = eResourceType;

        if (bReferenceFrame)
        {
            m_vRegisteredResourcesForReference.push_back(registerResource.registeredResource);
            m_vReferenceFrames.push_back(inputframe);
        }
        else
        {
            m_vRegisteredResources.push_back(registerResource.registeredResource);
            m_vInputFrames.push_back(inputframe);
        }
    }
}

Thank you
Stephen

emm, i am stuck in the same problem now

Hello,

Does anyone take a look at this problem ?

Nvidia driver 441.41 was released on Nov. 26th and it appears that it is also leaking.